{"id":16948702,"url":"https://github.com/technicalpickles/flamegraph-lighting-talk","last_synced_at":"2025-03-21T09:46:54.704Z","repository":{"id":156450646,"uuid":"632969265","full_name":"technicalpickles/flamegraph-lighting-talk","owner":"technicalpickles","description":null,"archived":false,"fork":false,"pushed_at":"2023-04-26T20:43:25.000Z","size":557,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-15T00:29:58.167Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/technicalpickles.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-26T13:56:30.000Z","updated_at":"2023-06-20T04:43:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"23e85fff-a00e-4cac-a480-ed279c007e4e","html_url":"https://github.com/technicalpickles/flamegraph-lighting-talk","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technicalpickles%2Fflamegraph-lighting-talk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technicalpickles%2Fflamegraph-lighting-talk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technicalpickles%2Fflamegraph-lighting-talk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technicalpickles%2Fflamegraph-lighting-talk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/technicalpickles","download_url":"https://codeload.github.com/technicalpickles/flamegraph-lighting-talk/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244776273,"owners_count":20508503,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T21:52:05.572Z","updated_at":"2025-03-21T09:46:54.680Z","avatar_url":"https://github.com/technicalpickles.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flamegraphs\n\n```\n      d'b 9                                                  8\n      8   8                                                  8\n     o8P  8 .oPYo. ooYoYo. .oPYo. .oPYo. oPYo. .oPYo. .oPYo. 8oPYo. .oPYo.\n      8   8 .oooo8 8' 8  8 8oooo8 8    8 8  `' .oooo8 8    8 8    8 Yb..\n      8   8 8    8 8  8  8 8.     8    8 8     8    8 8    8 8    8   'Yb.\n      8   8 `YooP8 8  8  8 `Yooo' `YooP8 8     `YooP8 8YooP' 8    8 `YooP'\n     :..::..:.....:..:..:..:.....::....8 ..:::::.....:8 ....:..:::..:.....:\n     :::::::::::::::::::::::::::::::ooP'.:::::::::::::8 :::::::::::::::::::\n     :::::::::::::::::::::::::::::::...:::::::::::::::..:::::::::::::::::::\n                                                                                       \n                                           %%                                          \n                                          *+*                                          \n                                         %+++%                                         \n                                         %+++%                                         \n                                          \\**                                          \n                                                                                       \n                                      \\**        %                                     \n                                    %*++*      /++/                                    \n                                   /++++*     /+++*                                    \n                                  %++++++    /+++++\\                                   \n                                  *++++++\\   \\+++++*                                   \n                                 /++++++++%  \\+++++/                                   \n                          **\\%   \\+++++++++/  *++\\%  %%%                               \n                          *+++*/ +++++++++++\\  // %\\+++*                               \n                          \\++++++++++++++++++*% %*++++\\                                \n                          /++++++++++++++++++++\\+++++*                                 \n                          \\++++++++++++++++++++++++++/    /**                          \n                          ++++++++++++=++++++++++++++\\   %+++\\                         \n                    \\*/  \\++++==++++++==++++=++++++++*   \\++++                         \n             /+*%   \\++**+++++===+++++====++=+++++++++/  *++++%                        \n             *+++   /+++++++++====+++=====++=++++++++++  *+++*                         \n           %*++++/  \\++++++++++==+++=======++++++++++++* /++*                          \n           *+++++/  *++++++==++++++========++===++++++++* %/%%                         \n          %+++++*  \\++++++++===+++========-=====+++++++++*% *+*                        \n           ++++\\  \\+++++++++====================+++++++++++*+++%                       \n           %*++/ \\++++==++++===========-========+++++++++++++++\\                       \n             /\\\\\\+++++-==+++=========---=========++=++++++++++++                       \n         \\\\\\%  \\++++++===++=========--:-===========-++++=+++++++/                      \n         ++++**++++++++=+++=========-:::-===========+++====+++++*                      \n         \\+++++++++++++++=======-----::::-===---=====+++===++++++                      \n         %+++++++++++==+========-::-::::::---:-=======+++-=++++++%                     \n          \\++++++++++===========-:::::::::::::-=======+++=+++++++                      \n           *++++++++=========----:::::::::::::-========+++++++++*                      \n           %*+++++++=========-:::::::::::::::::-========++===+++%                      \n             \\++++++-========-:::::::::::::::::--=-=========+++/                       \n              %*++++-=======-::::::::::::::::::::-:-========++/                        \n                %\\++====-==-:::::::::::::::::::::::-=======+*%                         \n                   /+==-:--:::::::::::::::::::::::::-=====\\%                           \n                     %\\+--::::::::::::::::::::::::::-=+\\%                              \n                         %/*+---::::::::::::::--=+*/%                                  \n                               %%//\\/////////%                                         \n                                                                               \n\n```\n\n[ascii source](https://github.com/rghvv/ASCII-Art-Generator/blob/fe4334d14a2dcbe8ea02ef052b796b0d4ead3bdd/Sample%20Outputs/fire.txt#L1)\ntext generation: `figlet -f jazmine -w 400 \"flamegraphs\"`\n\n\n## What are Flamegraphs?\n\n\n\u003e Flame Graphs visualize profiled code\n[brandangregg/FlameGraph](https://github.com/brendangregg/FlameGraph)\n\n\u003e Produces flame graphs from hierarchical data\n[spiermar/d3-flame-graph](https://github.com/spiermar/d3-flame-graph)\n\n\u003e A flame graph visualizes a distributed request trace and represents each service call that occurred during the request's execution path with a timed, color-coded, horizontal bar\n[DataDog: What is a Flame Graph? How it Works \u0026 Use Cases](https://www.datadoghq.com/knowledge-center/distributed-tracing/flame-graph/#:~:text=A%20flame%20graph%20visualizes%20a,fix%20bottlenecks%20in%20their%20applications.)\n\n\u003e Flame graphs are a visualization of hierarchical data, created to visualize stack traces of profiled software so that the most frequent code-paths to be identified quickly and accurately.\nhttps://www.brendangregg.com/flamegraphs.html\n\n\u003e A powerful tool for understanding how your program runs. And a great debugging tool.\n- me\n\n\n## Hi\n\nJosh Nichols\n\naka technicalpickles / techpickles\n\n4th-ish RailsConf? First in Vegas 2009\n\nI work at Gusto\n\nI like ascii art and vim\n\nI'm easily nerdsniped by performance issues\n\n## An example program\n\nLet's look at a program (simple.rb)\n\nWhat does this do? `hello` is called, which calls `world`, whicih calls `itsa`,\n\n```\n❯ ruby simple.rb\nmain\nhello\nworld\nitsa me pickles\nsup\nyall\n```\n\n## Profiling\n\nImagine we already have a tool to profile and visualize. Having seen a picture of a flamegraph, I could imagine it looking like..\n\n```\n[-------- main ----------------------------------------------]\n[--------------hello---][-------- sup ----------][-- yall--]\n      [-----------world]\n           [-------itsa]\n```\n\n## Caller\n\nThere's a handy ruby method `caller`\n\nShows the stack trace of the program at the time it's called\n\nLet's add that to our log message:\n\n```\n❯ ruby simple.rb                                                              ─╯\nmain\nsimple.rb:35:in `\u003cmain\u003e'\n\nhello\nsimple.rb:37:in `\u003cmain\u003e'\nsimple.rb:8:in `hello'\n\nworld\nsimple.rb:37:in `\u003cmain\u003e'\nsimple.rb:10:in `hello'\nsimple.rb:14:in `world'\n\nitsa me pickles\nsimple.rb:37:in `\u003cmain\u003e'\nsimple.rb:10:in `hello'\nsimple.rb:16:in `world'\nsimple.rb:20:in `itsa'\n\nsup\nsimple.rb:38:in `\u003cmain\u003e'\nsimple.rb:25:in `sup'\n\nyall\nsimple.rb:39:in `\u003cmain\u003e'\nsimple.rb:30:in `yall'\n```\n\nWhat if we lined them up horizontally?\n\n[simple.txt](simple.txt)\n\nThat is getting pretty close to the visualize.\n\nNow imagine constantly capturing these stack traces, and automatically grouping them like we just did\n\n## Flamegraph\n\nNow let's try looking at a real flamegraph.\n\nI've built a gem called [singed](https://github.com/rubyatscale/singed). Built on these excellent tools:\n\nIt wraps profiling your code with stackprof or rbspy, and then launching speedscope to view it.\n\n- [stackprof](https://github.com/tmm1/stackprof)\n- [rbspy](https://github.com/rbspy/rbspy)\n- [speedscope](https://github.com/jlfwong/speedscope)\n\n## Running it\n\nLet's run it:\n\n```\n❯ bin/singed ruby simple.rb\n🔥📈 Singed needs to run as root, but will drop permissions back to your user. Prompting with sudo now...\nPassword:\n$ sudo --preserve-env rbspy record --format speedscope --file /var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-cli-20230426102911.json --silent -- ruby simple.rb\nDropping permissions: running Ruby command as user josh.nichols\nrbspy is recording traces. Press Ctrl+C to stop.\nmain\nsimple.rb:35:in `\u003cmain\u003e'\n\nhello\nsimple.rb:37:in `\u003cmain\u003e'\nsimple.rb:8:in `hello'\n\nworld\nsimple.rb:37:in `\u003cmain\u003e'\nsimple.rb:10:in `hello'\nsimple.rb:14:in `world'\n\nitsa me pickles\nsimple.rb:37:in `\u003cmain\u003e'\nsimple.rb:10:in `hello'\nsimple.rb:16:in `world'\nsimple.rb:20:in `itsa'\n\nsup\nsimple.rb:38:in `\u003cmain\u003e'\nsimple.rb:25:in `sup'\n\nyall\nsimple.rb:39:in `\u003cmain\u003e'\nsimple.rb:30:in `yall'\n\nWrote raw data to /Users/josh.nichols/Library/Caches/rbspy/2023-04-26-wdxpGPf6CJ.raw.gz\nWrote formatted output to /var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-cli-20230426102911.json\n$ sudo --preserve-env chown josh.nichols /var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-cli-20230426102911.json\nCreating temp file /var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682519367683-10368.js\nCreating temp file /var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682519367683-10368.html\nOpening file:///var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682519367683-10368.html in your default browser\n```\n[link](file:///Users/josh.nichols/workspace/flamegraph-talk/node_modules/speedscope/dist/release/index.html#localProfilePath=/var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682519367683-10368.js)\nLooks pretty close\n\n## Aside\n\nFlames burn up, right? Not down?\n\nYeah, I don't know when we switched from them going up to down\n\nTheory: has to do with making it easier to read???\n\n## Interpretting this\n\nIf you are looking at a line, then the line above it called it\n\nWhen looking at a 'frame':\n- was called by the 'frame' above\n- calls the frame below it\n- for each point when there isn't a frame directly below it, time is spent in that method \n\nWe are using `sleep` so it's pretty clear time is _only_ in that frame\n\n\n## Rails\n\n\nSingle file rails app: rails.ru\n\nLet's run it:\n```\n❯ unicorn\n[2023-04-26 10:32:40] INFO  WEBrick 1.6.1\n[2023-04-26 10:32:40] INFO  ruby 2.7.5 (2021-11-24) [arm64-darwin21]\n[2023-04-26 10:32:40] INFO  WEBrick::HTTPServer#start: pid=10489 port=8080\n```\nAnd hit the endpoint\n\n```\n❯ unicorn -p 8080 rails.ru                                                                                                        ─╯\nI, [2023-04-26T10:39:54.485202 #11759]  INFO -- : listening on addr=0.0.0.0:8080 fd=11\nI, [2023-04-26T10:39:54.485247 #11759]  INFO -- : worker=0 spawning...\nI, [2023-04-26T10:39:54.486160 #11759]  INFO -- : master process ready\nI, [2023-04-26T10:39:54.486608 #11772]  INFO -- : worker=0 spawned pid=11772\nI, [2023-04-26T10:39:54.486829 #11772]  INFO -- : Refreshing Gem list\nI, [2023-04-26T10:39:55.050130 #11772]  INFO -- : worker=0 ready\nI, [2023-04-26T10:39:56.301871 #11772]  INFO -- : Started GET \"/\" for 127.0.0.1 at 2023-04-26 10:39:56 -0400\nI, [2023-04-26T10:39:56.310440 #11772]  INFO -- : Processing by RootController#index as */*\nD, [2023-04-26T10:39:59.316712 #11772] DEBUG -- :   Rendering text template\nI, [2023-04-26T10:39:59.317166 #11772]  INFO -- :   Rendered text template (Duration: 0.0ms | Allocations: 3)\nI, [2023-04-26T10:39:59.317764 #11772]  INFO -- : Completed 200 OK in 3007ms (Views: 5.4ms | Allocations: 909)\n\n\n🔥📈 Captured flamegraph, opening with: npx speedscope tmp/speedscope/speedscope-20230426103956.json\nCreating temp file /var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682519999729-11787.js\nCreating temp file /var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682519999729-11787.html\nOpening file:///var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682519999729-11787.html in your default browser\n127.0.0.1 - - [26/Apr/2023:10:39:59 -0400] \"GET / HTTP/1.1\" 200 - 3.4464\nD, [2023-04-26T10:46:44.948435 #11759] DEBUG -- : waiting 31.0s after suspend/hibernation\nD, [2023-04-26T10:53:25.286440 #11759] DEBUG -- : waiting 31.0s after suspend/hibernation\nD, [2023-04-26T10:58:26.551058 #11759] DEBUG -- : waiting 31.0s after suspend/hibernation\n^CI, [2023-04-26T10:58:39.436712 #11759]  INFO -- : reaped #\u003cProcess::Status: pid 11772 exit 0\u003e worker=0\nI, [2023-04-26T10:58:39.436922 #11759]  INFO -- : master complete\n```\n\n## Complexity\n\nDuring Eileen's keynote, she said something to the effect of:\n\nRails focuses on making develoepr experience simple, and does that by taking on complexity\n\nGuess what we are now seeing :D \n\nWe have to do a lot of scrolling to find our application code. This is pretty common, unfortunately.\n\n## Rails Boot time\n\n```\n❯ bin/singed  -- bin/rails runner true\n🔥📈 Singed needs to run as root, but will drop permissions back to your user. Prompting with sudo now...\nPassword:\n$ sudo --preserve-env rbspy record --format speedscope --file tmp/speedscope/speedscope-cli-20230426110625.json --silent -- bin/rails runner true\nDropping permissions: running Ruby command as user josh.nichols\nrbspy is recording traces. Press Ctrl+C to stop.\nWrote raw data to /Users/josh.nichols/Library/Caches/rbspy/2023-04-26-3kpcSoreui.raw.gz\nWrote formatted output to tmp/speedscope/speedscope-cli-20230426110625.json\n$ sudo --preserve-env chown josh.nichols tmp/speedscope/speedscope-cli-20230426110625.json\nCreating temp file /var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682521604552-12136.js\nCreating temp file /var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682521604552-12136.html\nOpening file:///var/folders/92/0kw80yh95bz8b431qwjvmctm0000gn/T/speedscope-1682521604552-12136.html in your default browser\n```\n\n## Be curious, learn by doing\n\nI've found it hard to teach this, but you can definitely learn by doing. And learn by working with people.\n\nFlamegraphs give you an opportunity to be curious. What is all that stuff? Let's find out!\n\n## Let's Collaborate\n\nIf you are interested in digging into Rails boot performance, or any really Ruby performance issues, please reach out!\n\nWould love to do some pairing 🍐\n\n## Conclusion\n\nJosh Nichols\n@technialpickles / @techpickles / @technicalpickles@ruby.social\n\n- https://github.com/technicalpickles/flamegraph-talk\n- https://github.com/technicalpickles/singed\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnicalpickles%2Fflamegraph-lighting-talk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechnicalpickles%2Fflamegraph-lighting-talk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnicalpickles%2Fflamegraph-lighting-talk/lists"}