# Profiling > https://docs.errora.org/en/products/profiling Profiling samples your process's call stacks while it works, so you can see where the time actually goes — inside the transaction that tracing already told you was slow. Errora accepts both profile shapes: - **Transaction profiles** (v1) — bounded by one transaction. - **Continuous profiling chunks** (v2) — a rolling stream, not tied to a transaction. ## Setup Profiling rides on tracing, so `traces_sample_rate` must be non-zero. ```python sentry_sdk.init( dsn="…", traces_sample_rate=0.2, profiles_sample_rate=1.0, # fraction *of sampled transactions* ) ``` ```javascript // Node.js import { nodeProfilingIntegration } from "@sentry/profiling-node"; Sentry.init({ dsn: "…", tracesSampleRate: 0.2, profilesSampleRate: 1.0, integrations: [nodeProfilingIntegration()], }); ``` ```php # Laravel .env SENTRY_TRACES_SAMPLE_RATE=0.2 SENTRY_PROFILES_SAMPLE_RATE=1.0 ``` `profiles_sample_rate` multiplies with `traces_sample_rate`: `0.2 × 1.0` means 20% of requests are traced and all of those are profiled. ## Reading a profile **Profiling** lists profiles with their transaction, duration, sample count, environment and release. Open one for: - **The flamegraph** — width is *time*, not sample count. Each sample is weighted by the gap to the next sample **on the same thread**, so a thread that happens to be sampled twice as often does not look twice as slow. Gaps are clamped, so a paused profiler can't dominate the graph. - **Self time per function** — the time spent in the function itself, excluding callees. - **Threads** — switch between them. **Slowest functions** for the whole project is its own view. That ranking is computed at ingest and stored per function, so it is an indexed query rather than a decompress-everything scan. ## API ```text GET /api/v1/projects/{project_id}/profiles?stats_period=24h&limit=&offset= GET /api/v1/projects/{project_id}/profiles/overview GET /api/v1/projects/{project_id}/profiles/functions GET /api/v1/projects/{project_id}/profiles/{profile_id} GET /api/v1/projects/{project_id}/profiles/{profile_id}/flamegraph ``` ## Cost Profiles are metered as the **Profiling** service, per profile. They are also the bulkiest payload the SDK sends, so keep `profiles_sample_rate` low in production once you have found your hot paths — or turn it up temporarily during an investigation. ## Troubleshooting | Symptom | Cause / fix | | --- | --- | | No profiles at all | `traces_sample_rate` is `0`, the profiling package isn't installed (Node needs `@sentry/profiling-node`), or the platform has no profiler | | Profiles but empty flamegraph | The transaction was too short to collect samples — profile a heavier endpoint | | Everything is `` | Native frames without symbols; ship a build with symbols, or profile the interpreted layer | | Costs climbing | Lower `profiles_sample_rate`; it multiplies with the trace sample rate |