Cell ArchitectureCAUTION
Developer-first error tracking and performance monitoring
Overview
Developer-first error tracking and performance monitoring
42a3375c14f5OBSERVED · 2026-09-29What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: cell-architecture
description: >-
Reference and active migration guide for Sentry's cell architecture. Explains what cells and
localities are and why they're different, how requests reach cells via Synapse API routing,
ingestion routing, and the control silo gateway, and how to safely query cross-cell data without
silently missing results. The migration section covers how to do migration work: draining the
URL_NAME_TO_ACTION registry in test_urls.py to zero (with a recipe for each action type),
rolling deploy safety and the two-phase pattern required by independent sentry/getsentry deploys,
and the region -> cell rename including what not to rename (DB columns, AWS refs, uptime regions,
billing address). Also documents known issues with proposed fixes: integration TeamLinkageView
routing, Jira cross-cell fan-out, and relocation endpoint routing.
---
> **Status**: Active migration in progress. Migration-specific sections should be removed once complete, leaving a stable architecture reference.
# Cells
## Cell vs Locality
These are two different layers of the architecture.
**Cell** — a self-contained Sentry deployment that owns a subset of organizations. Each cell
runs its own full stack — Getsentry, Snuba, Seer, Relay, Kafka, Symbolicator, and others —
on an isolated network with no direct cell-to-cell communication. `OrganizationMapping.cell_name`
records which cell an org lives in. See [Paths Into a Cell](#paths-into-a-cell) for how cells
communicate with the outside world.
**Locality** — a named collection of cells, representing either a data residency zone (for
multi-tenant customers, e.g. "us", "de") or a dedicated deployment for a single customer
(e.g. `s4s2`). Multi-tenant customers choose a locality when creating an organization;
single-tenant localities are provisioned privately and not customer-selectable. Each locality
maps to a subdomain (`us.sentry.io`, `de.sentry.io` or `s4s2.sentry.io`).
> **Note**: "region" is the old name for "cell". The codebase is actively being migrated.
> See [Active Migration](#active-migration) for details.
## Paths Into a Cell
There are three high-level paths by which requests or data reach a cell.
### 1. Locality API — `{locality}.sentry.io`
Synapse ([getsentry/synapse](https://github.com/getsentry/synapse)) routes each request to
the correct getsentry cell within a locality, using an **org to cell mapping** it caches from control's
`OrganizationMapping`.
```
us.sentry.io -> Synapse (API proxy) -> US cell(s)
de.sentry.io -> Synapse (API proxy) -> DE cell(s)
s4s2.sentry.io -> S4S2 cell (single cell, no Synapse)
```
For Synapse to route a request, the URL must contain `organization_id_or_slug`. The canonical
shape is `/api/0/organizations/<organization_id_or_slug>/...` — `getsentry/tests/getsentry/test_urls.py`
enforces this and fails CI for any `@cell_silo_endpoint` that doesn't conform.
When generating URLs for org-scoped resources, use `org.locality.to_url(path)` — derives the
correct locality URL across SaaS, self-hosted, single-tenant, and dev deployments:
```python
url = org.locality.to_url(f"/organizations/{org.slug}/issues/{issue.id}/")
```
For single-cell localities Synapse is an optional pass-through.
### 2. Ingestion — `ingest.{locality}.sentry.io`
A separate Synapse deployment routes each ingestion request to the correct cell using a **public key to cell mapping** it caches from control. The project config returned by Synapse includes the cell's Relay URL directly, which high-volume Relay deployments use to bypass Synapse for subsequent high-volume submission.
```
Standard: ingest.us.sentry.io -> Synapse (ingest-router) -> cell's Relay
High-volume: ingest.us.sentry.io ────────────────────────────-> cell's Relay
```
DSN hosts vary — legacy formats carry no locality or org info — so the ingest-router always routes by public key, which is present in every request regardless of DSN format.
The `o{org_id}.ingest.{locality}` subdomain also serves a second routing purpose: the user feedback embed widget (`sentry-error-page-embed`) posts to `sentry.io` with the project's DSN as a query param. Since the URL has no org slug, the API gateway can't route it the normal way — instead it parses the locality out of the DSN host. If the DSN was issued in a legacy format without a locality, the gateway can't determine the cell and the embed widget breaks silently for that org.
For single-cell localities the ingest-router is an optional pass-through.
### 3. Control silo — `sentry.io`
`sentry.io` is the getsentry control silo deployment. Control communicates with cells through three mechanisms:
**API Gateway** (`ApiGatewayMiddleware` -> `apigateway.py`) — synchronously proxies
org-scoped API requests that arrive at `sentry.io` but belong on a cell:
- Org slug/id in path, resolve cell via `get_cell_for_organization()`
- Error embed (`sentry-error-page-embed`) -> parse locality from DSN subdomain
- `REGION_PINNED_URL_NAMES` proxy to the monolith cell (the original US cell). Legacy endpoints like `/api/0/issues/{id}/` have no org slug so the gateway can't resolve the cell dynamically; they always route to US and will 404 for issues in other cells
**Integration webhook forwarding** (`IntegrationControlMiddleware` -> `BaseRequestParser`) —
inbound webhooks arrive at control, which identifies target cells via `OrganizationIntegration`. `organization_mapping_service`, then delivers using one of three strategies:
- **`WebhookPayload` async queue** (default; GitHub, most providers) — creates one record per
target cell, returns 202 immediately; background worker delivers with retries
- **Immediate ACK + async Celery task** (Slack, Discord) — returns ACK immediately, fires a
task that calls the cell and forwards the real response via the provider's callback URL
- **Control silo only** (setup flows, link/unlink, event challenges) — no cell forwarding
**RPC** — synchronous cross-silo calls.Trust audit
CAUTIONgrade B · trust 89/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | NA |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (2)
.claude/skills
api-docs/.node-version
Gates applied: no_behavioural_pass.
42a3375c14f5full audit observations/trust-audit/skill/getsentry__cell-architecture.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-09-29 | 42a3375c14f5 | CAUTION | B | 89 | first audit |
Questions
What does the Cell Architecture skill do?
Developer-first error tracking and performance monitoring
Is Cell Architecture safe to install?
With care. The audit graded it B (89/100) and found 2 things worth knowing before you trust this skill, listed below with the exact line each was found on.
What can Cell Architecture access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
How current is this page?
The grade is for one exact copy of the source (42a3375c14f5), read on 2026-09-29. The repository is watched, and a new audit runs when it changes — this is the first audit.