{"id":21660988,"url":"https://github.com/viraptor/rails_cold_spots","last_synced_at":"2026-04-04T16:34:17.600Z","repository":{"id":137746353,"uuid":"98527836","full_name":"viraptor/rails_cold_spots","owner":"viraptor","description":"Tools for profiling the initial rails request time","archived":false,"fork":false,"pushed_at":"2017-07-27T11:24:41.000Z","size":9,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-25T07:22:03.637Z","etag":null,"topics":["performance","profiling","rails","ruby"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/viraptor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2017-07-27T11:24:13.000Z","updated_at":"2017-07-27T23:26:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"eddd0a52-6e60-4ca1-965c-1b16ea9a7b48","html_url":"https://github.com/viraptor/rails_cold_spots","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/viraptor%2Frails_cold_spots","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viraptor%2Frails_cold_spots/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viraptor%2Frails_cold_spots/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viraptor%2Frails_cold_spots/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/viraptor","download_url":"https://codeload.github.com/viraptor/rails_cold_spots/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244560376,"owners_count":20472218,"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":["performance","profiling","rails","ruby"],"created_at":"2024-11-25T09:43:06.415Z","updated_at":"2025-12-31T00:07:42.307Z","avatar_url":"https://github.com/viraptor.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Analyzing cold request performance\n\nRequires `derailed_benchmark` branch with `perf:stackprof_warmup` command added: [get it here](https://github.com/viraptor/derailed_benchmarks/tree/warmup-tests)\n\nThe command allows you to take a profile the difference between the initial request and the later ones.\n\n# Finding the initial slowdown\n\nThe first request will normally do more work than the follow-up ones. One part of that is the things that the framework itself needs to initialize. For example starting the database connections, caching the schema, finding translations, etc. The other part is things that the application itself is doing. For example caching data from db queries which doesn't get refreshed for hours.\n\nSome of these things can be moved to the bootup process so that it doesn't affect the real request.\n\nThis script identifies 3 kinds of time sinks present only in the initial request:\n- framework-specific ones (for example initializing the methods on ActiveRecord models)\n- view-caching related (time per view / partial is summed up)\n- application-specific ones (explicit controller actions)\n\n# Usage\n\nFirst, the data collection needs to be run over multiple requests. The initial request profile is saved with suffix `.warm` and the follow-up ones with suffix `.cold.X`. For example:\n\n```\nfor x in $(seq 1 10) ; do\n  TEST_COUNT=10 PATH_TO_HIT=/ RAILS_ENV=production bin/derailed exec perf:stackprof_warmup\ndone\n```\n\nThis will make 10 cold request and for each of them 10 warm requests. (110 profiles in total) If the initial requests take ~1 second, this should be enough. If they take much shorter time, use either more iterations, or set `INTERVAL=20` (instead of the default 100us).\n\nThen, the profiles saved in `tmp/...` can be anaylsed. Run:\n\n```\npath_to/rails_cold_spots.py -k -m -t tmp\n```\n\nTo get a breakdown like:\n```\nAverage warmup time per request: 1953.5ms\n\nKnown time sinks:\napplication initiated queries                          :   5971,  30.6%,  597.1ms\nActiveRecord creating attribute methods on models      :   1832,   9.4%,  183.2ms\nActionDispatch building route cache                    :   1625,   8.3%,  162.5ms\n...\n```\n\nThe usual options mean:\n- `-k` - classify known time sinks\n- `-m` - remove common injected instrumentation, like NewRelic\n- `-t` - identify templates\n\nFor further debugging, there's also:\n- `-u` - try to merge one-off traces into bigger groups\n- `-f` - remove line numbers and process files only\n- `-v` - more verbose output\n- `-o N` - from the unidentified traces, show the N most common ones\n- `-l N` - when showing traces, list the top N frames only\n\n# Current status\n\nAlpha - it works, but the nice packaging is still coming\n\n# License\n\nCode distributed under Apache-2.0 license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviraptor%2Frails_cold_spots","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviraptor%2Frails_cold_spots","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviraptor%2Frails_cold_spots/lists"}