Linux Performance Analysis in 60 seconds
ํ์ค์ ์ธ Linux ํ๊ฒฝ์์ CLI๋ฅผ ์ด์ฉํด ์๋ฒ ์ํฉ์ 60์ด์์ ํ์ ํ๊ธฐ
Reference: netflixtechblog.com
Quick overview
$ uptime
$ dmesg | tail
$ vmstat 1
$ mpstat -P ALL 1
$ pidstat 1
$ iostat -xz 1
$ free -m
$ sar -n DEV 1
$ sar -n TCP,ETCP 1
$ top
First 60 Seconds: Summary
1. uptime
$ uptime
23:51:26 up 21:31, 1 user, load average: 30.02, 26.43, 19.02
uptime์ ํ์ฌ ๋๊ธฐ์ค์ธ process๊ฐ ์ผ๋ง๋ ์๋์ง ๋ํ๋ด๋ load average ๊ฐ์ ํ์ธํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ด๋ค
Linux system์์ ์ด ๊ฐ์ ๋๊ธฐ์ค์ธ process ๋ฟ๋ง ์๋๋ผ disk I/O ๊ฐ์ I/O ์์ ์ผ๋ก block๋ process๊น์ง ํฌํจ๋์ด ์๋ค
์ด๋ฅผ ํตํด์ ์ผ๋ง๋ ๋ง์ resource๊ฐ ์ฌ์ฉ๋๋์ง ํ์ธํ ์ ์์ง๋ง, ์ ํํ๊ฒ ๋ถ์ํ ์๋ ์๋ค
์์ ์๋ 3๊ฐ ์ซ์ (1.88 2.16 2.07)๋ ๊ฐ๊ฐ 1๋ถ, 5๋ถ, 15๋ถ์ load averageํ ๊ฐ์ด๋ค
์ด๋ฅผ ํตํด์ ์๊ฐ์ ๋ณํ๋ฅผ ์ ์ ์๋ค
ex)
์ฅ์ ๊ฐ ๋ฐ์ํ๋ค๋ ์์์ ๋ฃ๊ณ ํด๋น instance์ ๋ก๊ทธ์ธ ํ์๋ 1๋ถ ๋์์ ๊ฐ์ด 15๋ถ ๊ฐ์ ๋นํด์ ์๋ค๋ฉด,
์ด๊ฒ์ ์ฅ์ ๊ฐ ๋ฐ์ํ๊ณ , ๋๋ฌด ๋ฆ๊ฒ ๋ก๊ทธ์ธํ์์ ์ ์ ์๋ค.
์ ์์ ์์๋ 1๋ถ ๊ฐ์ด ์ฝ 30์ด๊ณ 15๋ถ ๊ฐ์ด 19 ์ ๋ ๋๋๊ฒ์ผ๋ก ๋ณผ๋ ์ต๊ทผ์ ์์นํ๊ฒ์ ์ ์ ์๋ค
์ฌ๊ธฐ์ ์ซ์๊ฐ ๋์ ๊ฒ์ ๋ง์ ์๋ฏธ๋ฅผ ๊ฐ๊ณ ์๋ค.
์๋ง๋ CPU ์์์ ๋ฌธ์ ๊ฐ ์์๊ฑฐ๋ผ ์ถ์ธก๋์ง๋ง ์ด ์๋ฏธ๋ฅผ ํ์ธํ๊ธฐ ์ํด์ ๋ค์ ๋์ค๋
vmstat
์ด๋mpstat
๊ฐ์ command๋ฅผ ์ด์ฉํด์ ํ์ธํ ์ ์๋ค.
2. dmes | tail
$ dmesg | tail
[1880957.563150] perl invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0
[...]
[1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child
[1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, file-rss:0kB
[2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request. Check SNMP counters.
dmesg๋ system message๋ฅผ ํ์ธํ ์ ์๋ command์ด๋ค
๋ถํ ์๋ถํฐ ์์ํด์ ๋ชจ๋ Kernel message๊ฐ ์ถ๋ ฅ๋๊ธฐ ๋๋ฌธ์ tail ์ ์ด์ฉํด์ ๋ง์ง๋ง 10์ค๋ง ์ถ๋ ฅํ ๊ฒ์ด๋ค
์ด ๋ฉ์ธ์ง๋ฅผ ํตํด์ ์ฑ๋ฅ์ ๋ฌธ์ ๋ฅผ ์ค ์ ์๋ ์๋ฌ๋ฅผ ์ฐพ์ ์ ์๋๋ฐ,
์์ ์์ ์์๋
oom-killer(out of memory)
์TCP request
๊ฐ drop๋๊ฒ์ ์ ์ ์๋ค.
3. vmstat 1
$ vmstat 1
procs ---------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
34 0 0 200889792 73708 591828 0 0 0 5 6 10 96 1 3 0 0
32 0 0 200889920 73708 591860 0 0 0 592 13284 4282 98 1 1 0 0
32 0 0 200890112 73708 591860 0 0 0 0 9501 2154 99 1 0 0 0
32 0 0 200889568 73712 591856 0 0 0 48 11900 2459 99 0 0 0 0
32 0 0 200890208 73712 591860 0 0 0 0 15898 4840 98 1 1 0 0
virtual memory stat์ ์ฝ์์ธ vmstat์ ์ ๋งํ ํ๊ฒฝ์์ ์ฌ์ฉ ๊ฐ๋ฅํ ํด์ด๋ค
1์ ์ธ์๋ก ์ค vmstat์ 1์ด๋ง๋ค ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค๋ค
์ฒซ๋ฒ์งธ ๋ผ์ธ์ ๋ถํ ๋ ๋ค์ ํ๊ท ์ ์ธ ๊ฐ์ ๋ํ๋ธ๋ค
ํ์ธํด๋ด์ผํ ํญ๋ชฉ
r
CPU์์ ๋์์ค์ธ ํ๋ก์ธ์ค์ ์ซ์์ด๋ค
CPU ์์์ด ํฌํ(saturation)๊ฐ ๋ฐ์ํ๋์ง ํ์ธํ ๋์ ์ข์ ๊ฐ์ด๋ค
r
๊ฐ์ด CPU์ ๊ฐ๋ณด๋ค ํฐ ๊ฒฝ์ฐ์ ํฌํ๋์ด ์๋ค๊ณ ํด์๋๋ค.
free
free memory๋ฅผ kb๋จ์๋ก ๋ํ๋ธ๋ค
free memory๊ฐ ๋๋ฌด ์๋ฆฌ์๊ฐ ๋ง์ ๊ฒฝ์ฐ
free -m
๋ฅผ ์ด์ฉํ๋ฉด ํธํ๊ฒ ํ์ธํ ์ ์๋ค
si, so
swap-in๊ณผ swap-out์ ๋ํ ๊ฐ์ด๋ค
0์ด ์๋๋ผ๋ฉด ํ์ฌ ์์คํ ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ๊ฒ์ด๋ค
us, sy, id, wa, st
๋ชจ๋ CPU์ ํ๊ท ์ ์ธ CPU time์ ์ธก์ ํ ์ ์๋ค
๊ฐ๊ฐ user time, ์ปค๋์์ ์ฌ์ฉ๋๋ system time, idle, wait I/O ๊ทธ๋ฆฌ๊ณ stolen time์์ด๋ค
stolen time์ hypervisor๊ฐ ๊ฐ์ CPU๋ฅผ ์๋น์ค ํ๋ ๋์ ์ค์ CPU๋ฅผ ์ฐจ์งํ ์๊ฐ์ ์ด์ผ๊ธฐํ๋ค
4. mpstat -p ALL 1
$ mpstat -P ALL 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
07:38:49 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
07:38:50 PM all 98.47 0.00 0.75 0.00 0.00 0.00 0.00 0.00 0.00 0.78
07:38:50 PM 0 96.04 0.00 2.97 0.00 0.00 0.00 0.00 0.00 0.00 0.99
07:38:50 PM 1 97.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 2.00
07:38:50 PM 2 98.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00
07:38:50 PM 3 96.97 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.03
[...]
์ด ๋ช ๋ น์ด๋ CPU time์ CPU ๋ณ๋ก ์ธก์ ํ ์ ์๋ค
์ด ๋ฐฉ๋ฒ์ ํตํ๋ฉด ๊ฐ CPU๋ณ๋ก ๋ถ๊ท ํํ ์ํ๋ฅผ ํ์ธํ ์ ์๋๋ฐ,
ํ CPU๋ง ์ผํ๊ณ ์๋๊ฒ์ application์ด single thread๋ก ๋์ํ๊ณ ์๋ค๋ ๋ป์ด๋ค
5. pidstat 1
$ pidstat 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
07:41:02 PM UID PID %usr %system %guest %CPU CPU Command
07:41:03 PM 0 9 0.00 0.94 0.00 0.94 1 rcuos/0
07:41:03 PM 0 4214 5.66 5.66 0.00 11.32 15 mesos-slave
07:41:03 PM 0 4354 0.94 0.94 0.00 1.89 8 java
07:41:03 PM 0 6521 1596.23 1.89 0.00 1598.11 27 java
07:41:03 PM 0 6564 1571.70 7.55 0.00 1579.25 28 java
07:41:03 PM 60004 60154 0.94 4.72 0.00 5.66 9 pidstat
07:41:03 PM UID PID %usr %system %guest %CPU CPU Command
07:41:04 PM 0 4214 6.00 2.00 0.00 8.00 15 mesos-slave
07:41:04 PM 0 6521 1590.00 1.00 0.00 1591.00 27 java
07:41:04 PM 0 6564 1573.00 10.00 0.00 1583.00 28 java
07:41:04 PM 108 6718 1.00 0.00 0.00 1.00 0 snmp-pass
07:41:04 PM 60004 60154 1.00 4.00 0.00 5.00 9 pidstat
pidstat์ process๋น
top
๋ช ๋ น์ ์ํํ๋๊ฒ๊ณผ ๋น์ทํ๋คbut, ์ฐจ์ด์ ์ ์คํฌ๋ฆฐ ์ ์ฒด์ ํ์ํ๋๊ฒ์ด ์๋๋ผ ์ง์์ ์ผ๋ก ๋ณํํ๋ ์ํฉ์ ๋์์ฃผ๊ธฐ ๋๋ฌธ์ ์ํฉ ๋ณํ๋ฅผ ๊ธฐ๋กํ๊ธฐ ์ข๋ค
์ ์์ ๋ฅผ ๋ณด๋ฉด ๋๊ฐ์ java process์ CPU ์ฌ์ฉ๋์ด ์์ฒญ๋๋ค
%CPU
ํญ๋ชฉ์ ๋ชจ๋ CPU์ ์ ์ฒด ์ฌ์ฉ๋์ ์๋ฏธํ๋ค๋ฐ๋ผ์ 1591%๋ฅผ ์ฌ์ฉ์ค์ธ java process๋ค์ 16CPU ๊ฐ๊น์ด ์ฌ์ฉ์ค์์ ๋ํ๋ด๋ ๊ฒ์ด๋ค.
6. iostat -xz 1
$ iostat -xz 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
73.96 0.00 3.73 0.03 0.06 22.21
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
xvda 0.00 0.23 0.21 0.18 4.52 2.08 34.37 0.00 9.98 13.80 5.42 2.44 0.09
xvdb 0.01 0.00 1.02 8.94 127.97 598.53 145.79 0.00 0.43 1.78 0.28 0.25 0.25
xvdc 0.01 0.00 1.02 8.86 127.79 595.94 146.50 0.00 0.45 1.82 0.30 0.27 0.26
dm-0 0.00 0.00 0.69 2.32 10.47 31.69 28.01 0.01 3.23 0.71 3.98 0.13 0.04
dm-1 0.00 0.00 0.00 0.94 0.01 3.78 8.00 0.33 345.84 0.04 346.81 0.01 0.00
dm-2 0.00 0.00 0.09 0.07 1.35 0.36 22.50 0.00 2.55 0.23 5.62 1.78 0.03
[...]
block device(HDD, SSD, โฆ)
๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง ์ดํดํ๊ธฐ ์ข์ ํด์ด๋คํ์ธํด๋ด์ผํ ํญ๋ชฉ
r/s, w/s rkB/s, wkB/s
read ์์ฒญ๊ณผ write ์์ฒญ, read kB/s, write kB/s๋ฅผ ๋ํ๋ธ๋ค
์ด๋ค ์์ฒญ์ด ๊ฐ์ฅ ๋ง์ด ๋ค์ด์ค๋์ง ํ์ธํด๋ณผ ์ ์๋ ์ค์ํ ์งํ๋ค
์ฑ๋ฅ ๋ฌธ์ ๋ ์๊ฐ๋ณด๋ค ๊ณผ๋ํ ์์ฒญ๋๋ฌธ์ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ ์๊ธฐ ๋๋ฌธ์ด๋ค.
await
I/O์ฒ๋ฆฌ ํ๊ท ์๊ฐ์ ๋ฐ๋ฆฌ์ด๋ก ํํํ ๊ฐ์ด๋ค
applicationํํ ๋ I/O์์ฒญ์ queueํ๊ณ ์๋น์ค๋ฅผ ๋ฐ๋๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ด๊ธฐ ๋๋ฌธ์ application์ด ์ด ์๊ฐ๋์ ๋๊ธฐํ๊ฒ ๋๋ค
์ผ๋ฐ์ ์ธ ์ฅ์น์ ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ๋ณด๋ค ๊ธด ๊ฒฝ์ฐ์๋ block์ฅ์น ์์ฒด์ ๋ฌธ์ ๊ฐ ์๊ฑฐ๋, ์ฅ์น๊ฐ ํฌํ๋ ์ํ์์ ์ ์ ์๋ค
7. free -m
$ free -m
total used free shared buffers cached
Mem: 245998 24545 221453 83 59 541
-/+ buffers/cache: 23944 222053
Swap: 0 0 0
ํ์ธํด๋ด์ผํ ํญ๋ชฉ
buffers: Block ์ฅ์น I/O์ buffer ์บ์, ์ฌ์ฉ๋
cached: ํ์ผ ์์คํ ์์ ์ฌ์ฉ๋๋ page cache์ ์
์ ๊ฐ๋ค์ด 0์ ๊ฐ๊น์ ์ง๋ฉด ์๋๋ค
์ด๋ ๊ณง ๋์ Disk I/O๊ฐ ๋ฐ์ํ๊ณ ์์์ ์๋ฏธํ๋ค (
iostat
์ผ๋ก ํ์ธ ๊ฐ๋ฅ)์ ์์ ๋ ๊ฐ๊ฐ 59MB, 541MB๋ก ๊ด์ฐฎ์ ์ ๋์ ์ํ๋ค
8. sar -n DEV 1
$ sar -n DEV 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:16:48 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:49 AM eth0 18763.00 5032.00 20686.42 478.30 0.00 0.00 0.00 0.00
12:16:49 AM lo 14.00 14.00 1.36 1.36 0.00 0.00 0.00 0.00
12:16:49 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:16:49 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:50 AM eth0 19763.00 5101.00 21999.10 482.56 0.00 0.00 0.00 0.00
12:16:50 AM lo 20.00 20.00 3.25 3.25 0.00 0.00 0.00 0.00
12:16:50 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
์ด ํด์ ์ฌ์ฉํ๋ฉด **network throughput(Rx, Tx KB/s)**์ ์ธก์ ํ ์ ์๋ค
์ ์์ ์์๋
eth0
์ ์์ ๋์ด ์ฝ 22Mbytes/s(21999.10rxkB/s)์ด๋ค์ด๊ฒ์ 176Mbits/s์ธ๋ฐ ํ๊ณ์ธ 1Gbit/s์ ์์ง ๋ง์ด ๋ชป ๋ฏธ์น๋ ๊ฐ์ด๋ค
์ ๊ฐ์ค
%ifutil
์ nicstat๋ก๋ ์ธก์ ๊ฐ๋ฅํ ๋คํธ์ํฌ ์ฅ์น ์ฌ์ฉ๋ฅ ์ด๋คbut, nicstat์์๋ ๊ทธ๋ ๋ฏ ์ ํํ ๊ฐ์ ๊ฐ์ ธ์ค๋๊ฒ ์ด๋ ค์์ ์ ์์ ์์๋ ์ ์๋ํ์ง ์๋๋ค
9. sar -n TCP,ETCP 1
$ sar -n TCP,ETCP 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:17:19 AM active/s passive/s iseg/s oseg/s
12:17:20 AM 1.00 0.00 10233.00 18846.00
12:17:19 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:20 AM 0.00 0.00 0.00 0.00 0.00
12:17:20 AM active/s passive/s iseg/s oseg/s
12:17:21 AM 1.00 0.00 8359.00 6039.00
12:17:20 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:21 AM 0.00 0.00 0.00 0.00 0.00
TCP ํต์ ๋์ ์์ฝํด์ ๋ณด์ฌ์ค๋ค.
active/s: ๋ก์ปฌ์์๋ถํฐ ์์ฒญํ ์ด๋น TCP ์ปค๋ฅ์ ์๋ฅผ ๋ณด์ฌ์ค๋ค (์๋ฅผ๋ค์ด, connect()๋ฅผ ํตํ ์ฐ๊ฒฐ).
passive/s: ์๊ฒฉ์ผ๋ก๋ถํฐ ์์ฒญ๋ ์ด๋น TCP ์ปค๋ฅ์ ์๋ฅผ ๋ณด์ฌ์ค๋ค (์๋ฅผ๋ค์ด, accept()๋ฅผ ํตํ ์ฐ๊ฒฐ).
retrans/s: ์ด๋น TCP ์ฌ์ฐ๊ฒฐ ์๋ฅผ ๋ณด์ฌ์ค๋ค.
active
์passive
์๋ฅผ ๋ณด๋๊ฒ์ ์๋ฒ์ ๋ถํ๋ฅผ ๋๋ต์ ์ผ๋ก ์ธก์ ํ๋๋ฐ์ ํธ๋ฆฌํ๋ค์ ์ค๋ช ์ ๋ณด๋ฉด active๋ฅผ outbound passive๋ฅผ inbound ์ฐ๊ฒฐ๋ก ํ๋จํ ์ ์๋๋ฐ, ๊ผญ ๊ทธ๋ ์ง๋ง์ ์๋ค.
ex) localhost์์ localhost๋ก ์ฐ๊ฒฐ๊ฐ์ connection
retransmits
์ ๋คํธ์ํฌ๋ ์๋ฒ์ issue๊ฐ ์์์ ์ด์ผ๊ธฐํ๋ค์ ๋ขฐ์ฑ์ด ๋จ์ด์ง๋ ๋คํธ์ํฌ ํ๊ฒฝ์ด๋(๊ณต์ฉ์ธํฐ๋ท), ์๋ฒ๊ฐ ์ฒ๋ฆฌํ ์ ์๋ ์ฉ๋ ์ด์์ ์ปค๋ฅ์ ์ด ๋ถ์ด์ ํจํท์ด drop๋๋๊ฒ์ ์ด์ผ๊ธฐํ๋ค
์ ์์ ์์๋ ์ด๋น ํ๋์ TCP ์๋ฒ๊ฐ ๋ค์ด์ค๋๊ฒ์ ์ ์ ์๋ค.
10. top
$ top
top - 00:15:40 up 21:56, 1 user, load average: 31.09, 29.87, 29.92
Tasks: 871 total, 1 running, 868 sleeping, 0 stopped, 2 zombie
%Cpu(s): 96.8 us, 0.4 sy, 0.0 ni, 2.7 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 25190241+total, 24921688 used, 22698073+free, 60448 buffers
KiB Swap: 0 total, 0 used, 0 free. 554208 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20248 root 20 0 0.227t 0.012t 18748 S 3090 5.2 29812:58 java
4213 root 20 0 2722544 64640 44232 S 23.5 0.0 233:35.37 mesos-slave
66128 titancl+ 20 0 24344 2332 1172 R 1.0 0.0 0:00.07 top
5235 root 20 0 38.227g 547004 49996 S 0.7 0.2 2:02.74 java
4299 root 20 0 20.015g 2.682g 16836 S 0.3 1.1 33:14.42 java
1 root 20 0 33620 2920 1496 S 0.0 0.0 0:03.82 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.02 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:05.35 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
6 root 20 0 0 0 0 S 0.0 0.0 0:06.94 kworker/u256:0
8 root 20 0 0 0 0 S 0.0 0.0 2:38.05 rcu_sched
top
๋ช ๋ น์ด๋ ์์์ ์ฒดํฌํด๋ณธ ๋ค์ํ ์ธก์ ์น๋ฅผ ์ฝ๊ฒ ์ฒดํฌํ ์ ์๋ค.์์คํ ์ ๋ฐ์ ์ผ๋ก ๊ฐ์ ํ์ธํ๊ธฐ ์ฝ๋ค๋ ์ฅ์ ์ด ์๋ค
but, ํ๋ฉด์ด ์ง์์ ์ผ๋ก ๋ฐ๋๋ ์ ๋๋ฌธ์ ํจํด์ ์ฐพ๋๊ฒ์ด ์ด๋ ต๋ค
์ผ์์ ์ผ๋ก ๋ฉ์ถ๋ ํ์์ ์ก๊ธฐ ์ํด์๋ ํ๋ฉด์ ์ฃผ๊ธฐ์ ์ผ๋ก ๋น ๋ฅด๊ฒ ๋ฉ์ถฐ์ฃผ์ง ์์ผ๋ฉด ์ฐพ๊ธฐ ํ๋ค๋ค
ex) ctrl+S๋ ์ ๋ฐ์ดํธ๋ฅผ ์ค์ง์ํค๊ณ , Ctrl+Q๋ ๋ค์ ์์์ํจ๋ค. ๊ทธ๋ฆฌ๊ณ ํ๋ฉด์ด ์ง์์ ธ๋ฒ๋ฆฐ๋ค
Last updated
Was this helpful?