Skip to content

The map shows what runs where, read off the providers you connect, and how each piece depends on the others. Where the catalog records who owns a service, the map records what that service runs on, and the two meet when you link them.

Open it from Map in the sidebar, under Respond.

Each connection to a provider that runs or holds infrastructure puts what it reaches on the map, with a link to the resource’s page on the provider where it has one.

ConnectionWhat it puts on the map
AWSECS services, App Runner services, Elastic Beanstalk environments, Lambda functions, EC2 instances, RDS databases and CodeBuild projects in each region the connection reads, and the CodePipeline pipelines, CodeDeploy deployment groups and CloudFormation stacks that release them, each linked to what it releases. A CodeBuild project shows how its newest build ended, or that it is building
AzureApp Service and Function apps, Container Apps and the hostnames they serve, Azure SQL databases, PostgreSQL flexible servers and container registries
Azure DevOpsThe repositories and pipelines of the projects the connection reads, each pipeline linked to the repository it builds, and what the repositories’ infrastructure files define
BitbucketThe workspace’s repositories, and what their infrastructure files define
CircleCIEach project the token reaches, as a pipeline, linked to the repository it builds when CircleCI says which
ClickHouseEach service in the organizations the connection reaches, as a database, and the ClickPipes that load data into it, as pipelines
CloudflareZones and their hostnames, Workers, Pages projects, R2 buckets, D1 databases, KV namespaces, queues, Hyperdrive configurations, Tunnels, load balancers and their pools, and Access applications
ConvexThe deployment, under its project
DigitalOceanApps, the domains they serve and the repositories they build from, Droplets and databases
Fly.ioApps with their machines and the hostnames their certificates cover, and Managed Postgres clusters with the apps attached to them
GitHubThe repositories the connection sees, and what their infrastructure files define
GitLabThe projects the token sees, and what their infrastructure files define
Google CloudCloud Run services and the addresses they serve, Cloud Run jobs, Cloud SQL instances, Compute Engine instances, GKE clusters, and Cloud Deploy delivery pipelines with a release flow for each stage, linked to the Cloud Run services and jobs they released
KubernetesWorkloads, services and ingresses in the connected namespaces, with what serves what
ModalThe environment’s deployed apps
NeonProjects, their branches, the computes serving each branch, the databases on it and its Neon Functions
NetlifySites, the domains they serve and the repository each builds from
NorthflankServices, build services, databases and jobs in each project the connection reads, the repository each one builds from, the domains on each service’s public ports, and the project’s workflows, its pipelines and the release flow of each pipeline stage, each linked to what it releases
PlanetScaleEvery database in the organizations the connection reaches, and each database’s branches
PostgreSQLThe one database the connection reaches
RailwayServices, databases and cron jobs in the chosen environment of each project the connection reads, the repositories they build from and the domains they serve
RenderServices, static sites, cron jobs, datastores and workflows, the repositories services and workflows build from and the domains they serve
SupabaseEvery project the connection reaches, as a database, its preview branches and its Edge Functions
TinybirdThe workspace’s data sources and API endpoints, each endpoint linked to the data sources it reads
Trigger.devThe tasks of the newest version deployed to the environment, as jobs
TursoThe databases the organization or group holds, and the branches made from them
UpstashRedis databases, the QStash of each region, each workflow that ran recently and each active Box
VercelProjects, the repository each builds from and the verified domains it serves

Some connections read more than one place, chosen when you connect: Northflank and Railway projects, Render workspaces, Vercel teams, Bitbucket workspaces, Azure DevOps projects, Google Cloud projects and Azure subscriptions. Pick one, several, or all the credential can read. Choosing all takes in one added later at the next read.

Firefight reads each connection every hour, and right after you connect or refresh one. GitHub, GitLab, Bitbucket, Azure DevOps and Cloudflare change slowly next to a deploy, so they are read once a day. People who can manage integrations can press Sync now at the top of the map to read every connection again straight away. Many connections also tell Firefight about a change as it happens, see Live updates.

A few things decide how complete the map is:

  • Northflank jobs need the token’s role to have Project > Jobs > General > Read, workflows Project > Workflows > General > Read, and pipelines and their release flows Project > Pipelines > General > Read. Without one of them, the map lists everything else and says what could not be read and the permission to add.
  • Cloudflare, ClickHouse, Neon, PlanetScale, Supabase, Turso and Upstash are read through the connection’s own tools, so the tools that list what it holds must be switched on for the connection under Integrations. For PlanetScale those are planetscale_list_organizations, planetscale_list_databases and planetscale_list_branches, and Cloudflare needs execute. A tool that is off is named as the reason something is missing.
  • Neon Functions are read on each project’s default branch and its 24 most recently changed branches. An Upstash workflow shows while one of its runs is among its region’s latest 50, so a workflow that has not run lately leaves the map until it runs again.

Anything a connection could not read is listed under Not read in the panel beside the map, so a missing resource is known to be missing. The same list says when a connection’s last sync failed, or when its normal readings or usual log lines could not be read.

  • Map draws each account as a box, arranged in the direction things depend. A resource with an open incident is outlined in red, and one with no links is drawn fainter. The panel beside it lists what needs attention now, what changed in the last 24 hours (a deploy, a status that moved, a service that scaled, a setting that changed, something new or gone), what waits for your review, each connection’s live updates, and anything Not read.
  • Focus shows one resource and everything one, two or three links away. Choose What it needs to follow what it depends on, What needs it to see what would stop if it failed, or Both ways. The panel beside it tells you everything about the resource, see A resource’s panel.
  • Table lists every resource, ranked by how many others depend on it, with its links, the catalog entries it runs, its incidents over the last 30 days, its last change and any open incident. Only resources with no links shows what is not connected to anything yet.

Search, environment, provider and type filters narrow the Map and Table views. The view and the resource in focus are part of the page address, so you can share a link to exactly what you are looking at.

Open a resource in Focus, or click it on the map, and the panel beside it reads top to bottom:

SectionWhat it shows
What it isIts kind, provider, account, environment and last status, details such as its plan, region or Instances, and Open in the provider
Runs, from the catalogThe catalog entries it runs, with what each is for and who owns it, as written in the catalog
NowIts open incidents
Key checksThe first readings worth taking, see Key checks
Past incidentsUp to five incidents that ended on it in the last 180 days, each with one line on how it ended
Normal, over the last weekWhat each metric usually reads, the level 95% of readings stay under, and the peak
Usual log linesThe kinds of line it usually prints, see Usual log lines
Settings that point hereOn a database, the settings of services that name it, see Which services use which databases
Links and how they were foundEach link, and Add link, see Links and how they were found
If it failsWhat stops with it, and what else would stop if the suggested links are right
Halon remembersWhat Halon has learned about it, shown when Halon is on for your workspace
What changedIts recent changes, such as deploys, status moves, scaling and settings

A past incident’s line comes from the completed postmortem’s summary first, then the incident’s summary. The running summary of the channel is used only when the incident is not private and your workspace lets people read transcripts. Now and Past incidents stay empty until a catalog entry is linked, since an incident names a catalog service, not a resource.

Normal is read once a day from a week of the provider’s own metrics, never estimated. When an observability tool you connect also watches the resource, its readings show beside the provider’s with its name, such as CPU (Datadog). A connection whose metrics could not be read says so under Not read.

A service’s panel shows Instances, how many copies of it the integration runs or is set to run. When the count changes between one sync and the next, or when a live update says the service changed, the map records it as a scale, such as “web went from 2 to 6 instances”. It shows in what changed, Halon reads it as a change worth checking when something fails soon after, and it can start a Service scaled workflow.

IntegrationWhat counts
NorthflankThe instances a service is set to run
RenderThe instances a service runs, which autoscaling moves too
RailwayThe replicas a service is set to run
Fly.ioAn app’s Machines
KubernetesThe replicas a deployment or stateful set wants, which an autoscaler moves too, and the pods a daemon set schedules
AWSThe tasks an ECS service is set to run, which service auto scaling moves too
ModalThe containers an app runs when the map reads it
DigitalOceanThe instances an app’s services and workers run
Google CloudThe instances of a Cloud Run service set to manual scaling
AzureThe instances of an App Service or Function app’s plan, and the replicas of a Container App whose fewest and most are the same

A service that scales on its own with no one number to read, such as a Cloud Run service on automatic scaling, a DigitalOcean app with an autoscaling component, an Azure Consumption or Elastic Premium plan, App Runner and Elastic Beanstalk, shows no count rather than a guess. Vercel, Netlify, Cloudflare, Convex and Trigger.dev run code on demand, and code hosts and databases run no copies of a service, so none of them has a count.

A link reads as “this depends on that”, such as web runs builds of firefight, or app.example.com is served by web. Every link says how it was found.

How it was foundWhat it means
Declared by the connectionThe provider reports it, such as the build a service runs or the repository a build comes from. It goes away when the provider stops reporting it, so you cannot remove it by hand.
Matched from a settingOne of the service’s settings, such as DATABASE_URL, names the exact address the database’s own provider reports for it. It is a fact, drawn solid, and it lists the settings it came from. It goes away when the setting stops naming that address, so you cannot remove it by hand.
Added by a personSomeone added it with Add link because no provider reports it, such as a service that uses a database it reaches with a secret.
Suggested by FirefightFirefight worked it out from clues, such as a service and a database named for the same project, a setting whose name points at a database’s provider, or a resource named in a repository’s infrastructure files, which suggests it is managed in that repository. It is drawn dashed until someone confirms it.
Suggested by HalonHalon found it from evidence, such as connections to a database’s host in a service’s logs, and wrote down what it saw. It is drawn dashed until someone confirms it.

The infrastructure files a code host is read for are files such as Terraform, Helm charts, Kubernetes manifests, Pulumi and CDK programs, and a platform’s own config, like wrangler.toml, fly.toml or vercel.json.

To add a link, open a resource in Focus and choose Add link under Links and how they were found. Pick what it depends on and how, and say how you know if you like. Remove link takes away a link someone added or a suggestion someone confirmed, after you confirm. On a link the provider reports or a setting names, Remove link stays inactive and its tooltip says why.

Suggestions appear under To review on the map and on the resource they start from, each with the clues behind it and how sure it is. Confirm link makes it part of the map. Dismiss removes it, and the same link is not suggested again.

A workflow or a pipeline’s release flow is linked to what it releases, such as web is released by shop Production, and a release flow is part of its pipeline. On AWS a pipeline is linked to the services, deployment groups, stacks and Elastic Beanstalk environments its deploy actions name, a CodeDeploy deployment group to the ECS services it deploys, and a CloudFormation stack to every resource it made. On Google Cloud each stage of a Cloud Deploy pipeline is linked to the Cloud Run services and jobs it released. A release failing stops nothing that is already running, so these links never count toward what stops if something fails.

Until you confirm a suggestion, it does not count toward what stops if something fails. The If it fails section in Focus lists the facts first, then what would also stop if the suggested links are right, and the table’s Depended on by column counts facts with suggestions shown beside them.

Adding, removing, confirming and dismissing links needs permission to change the catalog.

A service says which database it uses in its settings, such as DATABASE_URL=postgres://app:...@ep-cool-river.eu-central-1.aws.neon.tech/app. On every sync Firefight reads each service’s settings where the connection allows it, and compares the address in each one with the addresses database providers report for their own databases. The value is never stored, shown, logged or handed to Halon, and neither is the password inside it. Firefight keeps only the setting’s name.

When a setting names the address of exactly one database, the service is linked to that database as a fact, with the setting’s name on the link. A database’s panel in Focus lists them under Settings that point here, such as DATABASE_URL from web.

Some matches are not certain, so they stay suggestions for you to confirm:

How sureWhen
LikelyA PlanetScale MySQL setting names PlanetScale’s shared host and a database of the same name, which another account could also have. Or the service and the database are named for the same project and the same environment, or for the same project with a setting whose name points at the database’s provider, such as NEON_DATABASE_URL. A service with no environment in its name, such as web, is taken as production.
PossibleThey are named for the same project, but the database’s name says nothing about its environment. Or a setting’s name points at a provider or a kind of database, such as REDIS_URL, its value is hidden or names no address a provider reported, and only one database fits. Or two databases report the same address.

A service and a database named for different environments, such as dev-web and firefight-prod, are never suggested. A likely link is drawn dashed and a possible one dotted, and both stay suggestions until you confirm them. A suggestion you dismiss is never made again, even if a setting later names that database.

Some providers hide a setting’s value, such as a secret on Fly.io, a sensitive variable on Vercel, a sealed variable on Railway or a Kubernetes Secret. Firefight never asks for those values, so such a setting counts only by its name.

Every connection works with the access it already asks for. A few providers keep some settings behind extra access, which you can add if you want those services linked too. All of it is optional.

ConnectionWhat to addWhat it links
AzureA custom role on the apps holding only Microsoft.Web/sites/config/list/actionApp Service and Function apps to the databases their app settings and connection strings name. Container Apps are linked without it.
KubernetesA rule letting the service account get configmaps in the connected namespacesWorkloads whose settings come from a ConfigMap. Secrets are never read.
Trigger.devAn API key whose preset can read environment variables, instead of ObserverTasks to what the environment’s variables name. Observer keeps the connection read only.

Two connections ask for the access their settings need when you connect them. Each still works without it, and only these links are missing:

ConnectionWhat the connect form asks forWhat is not linked without it
NorthflankPermission for the token’s role to read secret groupsServices and the databases linked to the secret groups they use.
AWSecs:DescribeTaskDefinitionECS services and the databases their task definitions name. Lambda functions are still linked.

Without any of this access, the map lists what it could not read under Not read, and everything else still links.

In Focus, under Runs, from the catalog, choose Link a catalog entry to say which catalog entry a resource runs, such as linking the web service on Northflank to your Checkout service in the catalog.

Once they are linked, an incident that names that catalog service in its fields lights up the resource on the map, shows under Now in its panel, and counts toward its incidents over 30 days. Its panel shows what the service is for and who owns it, and how its incidents ended. A linked service, worker, job or function joins the daily read of usual log lines. Halon also reads the resource as where that service runs, and an investigation into an incident starts from the resources its services run on and what changed there before it began. Linking needs permission to change the catalog, and the x on an entry unlinks it after you confirm.

Most connections tell Firefight when something changes, or keep a log of changes Firefight reads every few minutes, so the map follows a change long before the next scheduled read. When a change arrives, Firefight reads that resource again and updates what is different, such as its status, the commit it runs, its domains and the settings that link it to a database. A resource the provider no longer has leaves the map.

ConnectionHow changes arriveWhat brings an update
AWSCloudTrail’s event history, read every 5 minutes in each region, and optionally a stack you create, see AWSSee AWS
AzureThe subscription’s activity log, read every 5 minutes, and optionally Event Grid, see AzureAny change to an App Service or Function app, a Container App, an Azure SQL database, a PostgreSQL flexible server or a container registry, including one deleted
Azure DevOpsService hooks Firefight addsA push to a repository’s default branch, and a repository created, deleted or renamed
BitbucketA webhook Firefight addsA repository created, imported, deleted, renamed or transferred, and a push to a repository’s main branch
CircleCIWebhooks Firefight adds, one per projectA workflow or a job ending. These change nothing on the map, and let a watch hear at once
ClickHouseEach service’s state and its ClickPipes’ states, read every 5 minutesA service starting, stopping, idling or changing state, a service added or removed, and a ClickPipe added, removed, starting, pausing, stopping or failing
CloudflareEach account’s audit log, read every 5 minutes, and optionally a Pages notification you send, see Cloudflare Pages notificationsA change to a zone, its DNS records or settings, a Worker, a Pages project, an R2 bucket, a D1 database, a KV namespace, a queue, a Tunnel, a load balancer pool or a Hyperdrive configuration
ConvexA log stream Firefight adds once you turn it on, see ConvexCode pushed to the deployment, the deployment paused or unpaused, and a change to its settings
DigitalOceanEach app’s events, read every 5 minutesA deployment starting, moving to its next phase or ending, autoscaling changing how many instances a component runs, and an app deleted
Fly.ioEach app’s machines and newest release, read every 5 minutesA machine starting, stopping or changing, a release starting, finishing or failing, and an app being created or deleted
GitHubFirefight’s GitHub appA repository created, deleted, archived, unarchived, renamed, moved or given another default branch, repositories added to or removed from Firefight’s GitHub app, and a push to the default branch that changes an infrastructure file
GitLabA webhook Firefight addsA push to the default branch that changes an infrastructure file, and a project created or deleted in the group Firefight follows
Google CloudThe project’s audit log, read every 5 minutesAny change to a Cloud Run service, Cloud SQL instance, Compute Engine instance or GKE cluster, including one created or deleted, and a Cloud Build build starting or ending, on the Cloud Run services its trigger deploys
KubernetesA watch on the cluster every 2 minutesA deployment, statefulset, daemonset, cronjob, job, service or ingress in the connected namespaces being created, changed or deleted
ModalThe environment’s apps, read every 5 minutesAn app deployed, rolled back or stopped, and a new app deployed or one removed
NeonEach project’s operations, read every 5 minutesA compute starting, suspending or changing, and a branch being created, deleted, archived or restored
NetlifyWebhooks Firefight addsA production deploy being published, and an earlier deploy being published again
NorthflankA webhook Firefight addsA service deploying, building or scaling, a container crashing, being evicted or staying near its memory or CPU, a database backup starting or ending, a database’s disk filling up, a job run starting, ending or being stopped, and a release flow run starting, moving or ending
PlanetScaleA webhook Firefight adds to each database, or one you add, see PlanetScaleA branch becoming ready, going to sleep, starting maintenance or getting a new primary, and a deploy request moving through its steps
RailwayA webhook Firefight addsA deployment changing status, such as building, deploying, deployed, failed, crashed, out of memory, sleeping, resumed, restarted or removed, and a CPU, memory or volume alert you set up in Railway firing or resolving
RenderA webhook Firefight addsA build or deploy starting or ending, a service suspended, resumed or scaled, a cron job or one-off job running, an instance failing, a service’s instance type changing, a Postgres datastore created, becoming available or unavailable, restarting or upgrading, and a Key Value datastore becoming available or unhealthy or restarting for a new configuration
SupabaseAn endpoint you create, see SupabaseA project created, paused, restored, restarted, removed, moved to another organization, changing status or starting a backup, and a preview branch created, updated or removed
Trigger.devAlerts you add, see Trigger.devA deployment succeeding
VercelA webhook Firefight addsA production deployment starting, becoming ready, succeeding, failing or being canceled, a promotion or rollback, a rolling release starting, moving on, completing or being stopped, a project created, removed or renamed, an environment variable changing, and a domain added to a project, verified, changed, moved, removed or no longer verified

A change sent by webhook reaches the map within about a minute. A change read from a log or a check takes a little longer:

ConnectionReaches the map within about
Kubernetes3 minutes
ClickHouse, Cloudflare, DigitalOcean, Fly.io, Google Cloud, Modal, Neon6 minutes
AWS, from CloudTrail10 minutes, since CloudTrail itself takes around 5 minutes to record a change
Azure25 minutes from the activity log, since Azure adds a change to it 3 to 20 minutes after it happens, or about a minute with Event Grid turned on

PostgreSQL, Tinybird, Turso and Upstash send no changes Firefight can follow, so they update at each hourly read.

Some changes bring no update, and reach the map at the next scheduled read instead:

  • Render sends nothing when a service is created or deleted, or when its settings change. A workflow’s task runs send nothing either, so a watch on one checks it every minute.
  • Railway sends nothing when a service is created, renamed or deleted, or when its variables change.
  • Northflank and Netlify send nothing when a service, database, job or site is added or removed, or when its settings change. Northflank sends nothing when a workflow or pipeline is added or removed, or when a workflow runs.
  • PlanetScale sends nothing when a branch is resized or its settings change. A database added since gets Firefight’s webhook at the next hourly read.
  • Azure DevOps sends nothing when a pipeline is added, renamed or removed, so pipelines change on the map at the daily read.
  • CircleCI sends nothing when a project is added or removed, so a new project waits for the hourly read. A connection made through CircleCI’s own MCP server cannot add webhooks, so its live updates stay off and say so.
  • ClickHouse changes to a service’s settings, or to where a ClickPipe reads from, wait for the hourly read.
  • Convex sends nothing about what its functions print, which Halon reads when it needs it.
  • DigitalOcean follows apps only. A Droplet or a database changing, and an app added, wait for the hourly read. A team with more than 100 apps is read 100 apps at a time, so a change there can take longer.
  • Modal changes to how many containers an app runs wait for the hourly read.
  • Trigger.dev follows only the alerts you send to Firefight, and only a deployment succeeding changes the map. A failed run, a failed deployment or an error group alert has Halon check its watches at once.
  • Supabase sends nothing for an organization or project you did not create an endpoint for.
  • Neon reaches only the projects already on the map, so a new project waits for the hourly read. A Neon Function’s new deployments wait for the hourly read too.
  • Fly.io changes to an app’s certificates or Managed Postgres clusters wait for the hourly read.
  • Kubernetes changes to a ConfigMap a workload reads, or to the labels a service picks a workload by, wait for the hourly read.
  • Cloudflare keeps a renamed DNS record’s old hostname on the map until the daily read.
  • GitLab sends nothing when a project is renamed, moved or given another default branch, and Bitbucket nothing when a repository is given another main branch. A change to a Pulumi or CDK program outside a folder named infra, infrastructure, stacks, cdk or pulumi brings no update either. These wait for the daily read.
  • Bitbucket says a repository was deleted only once it is gone for good, which can take 30 days, so a deleted repository usually leaves the map at the daily read first.

Changes that touch nothing on the map bring no update at all, such as a preview deployment on Vercel, a deploy preview or branch deploy on Netlify, a push to a code host that changes no infrastructure file, or writing a value to a KV namespace, running a query on a D1 database or purging a cache on Cloudflare. While live updates are on, each connection’s details say what they do not follow.

Each connection’s details under Integrations say whether live updates are on, and so does the Live updates section of the panel beside the map:

  • Live updates: on, last event 3 minutes ago means changes reach the map as they happen.
  • Live updates: on, no change received yet means Firefight is ready and has heard nothing so far.
  • Live updates: off comes with the reason, such as the connection being switched off, the access it is missing, or the provider not letting Firefight add its webhook, quoting what the provider answered. The map still updates at each scheduled read.

When a provider turns Firefight’s webhook or its read down, Firefight tries again once a day, so live updates turn on by themselves once the provider allows it. For a webhook Firefight adds, people who can manage integrations can press Turn on to try again straight away. For a connection Firefight reads every few minutes, pressing Refresh tools on the connection under Integrations tries straight away.

When you connect one of these, Firefight adds a webhook of its own with the connection’s access, and there is nothing for you to set up:

ConnectionWhere the webhook goesWhat it is called
Azure DevOpsEach project the connection reads, as service hooks under Service hooks in the project’s settings-
BitbucketThe workspaceFirefight live updates
CircleCIEach project the token reachesFirefight live updates
GitLabThe group every project the token reaches is in, or the one project it reachesFirefight live updates
NetlifyEvery site the token reaches, one for each event it follows-
NorthflankYour team’s notification integrations, sending events from the connected project onlyFirefight live updates followed by the project and a short code
PlanetScaleEach database on the map, see PlanetScale-
RailwayThe project, under Settings → Webhooks on Railway-
RenderThe workspaceFirefight live updates
VercelThe team-

You can see it in the provider’s webhook settings. Firefight never changes or removes a webhook you made. Removing the connection in Firefight removes its webhooks, and adding and removing them appear in Activity under the Map sweep source.

A Netlify site you add later gets its webhooks within the hour, and Firefight turns a webhook back on if Netlify switched it off after deliveries failed. Railway’s webhook covers the whole project, pull request environments included, so a project connected once per environment has one webhook per environment, and each updates only its own environment on the map. A deployment in a pull request environment does not reach the map, and a watch Halon keeps on it checks again straight away. When Firefight starts following more events for Render, Railway, Netlify, Vercel or Azure DevOps, it updates the webhook it added at the next read, and there is nothing for you to do.

Adding the webhook needs some access on the provider’s side:

  • Northflank needs the API token’s role to read, create and delete notification integrations (Account > Observability > Notifications).
  • GitLab needs a token with the api scope. A group webhook needs the Owner role in the group and a group on GitLab Premium or Ultimate, and a project webhook needs the Maintainer role. A token that reaches projects in more than one group gets no live updates, so connect a group access token for each group instead. This works the same on your own GitLab.
  • Bitbucket needs a workspace owner’s token with the read:webhook:bitbucket, write:webhook:bitbucket and delete:webhook:bitbucket scopes.
  • Azure DevOps needs a token from a project administrator of each project, with Service Hooks (Read, query, & manage).
  • CircleCI needs the token’s user to manage each project’s settings. When CircleCI lists more projects in an organization than Firefight reads at once, live updates stay off and say so.

GitHub needs no webhook. Firefight’s GitHub app sends updates for every repository you installed it on.

A Render workspace may have room for only one webhook, and Render does not say how many a workspace is allowed. When a workspace has no webhooks yet, Firefight’s could be its only one, and the workspace could then not add one of its own. The same goes for a workspace one short of the most Render allows. In those cases Firefight does not add its webhook on its own. Firefight asks the same way for a Convex deployment, which can send to only one webhook log stream, and a PlanetScale database that already has four of the five webhooks PlanetScale allows. The connection shows Live updates: off with what adding it would mean, and a Turn on button.

Pressing Turn on shows that explanation again before anything changes. Confirm, and Firefight adds its webhook and says so. Once it is on, Turn off removes Firefight’s webhook again, which frees the room for one of your own, and Firefight does not add it back until someone turns live updates on. A Render workspace that already has a webhook of its own gets live updates without asking. Azure’s Event Grid is turned on the same way, see Azure. When the button cannot be used, it stays on the connection greyed out, and hovering it says why.

When the connection reaches PlanetScale’s API, Firefight adds its own webhook to each database on the map, and to a database added later at the next hourly read. A connection reaches the API when you signed in to PlanetScale, or connected with a service token and its id, see Connect an integration. Each addition appears in Activity under the Map sweep source.

If one of your databases already has four of the five webhooks PlanetScale allows, Firefight’s would take the last one, so it does not add any on its own. The connection shows Live updates: off with which database that is and a Turn on button, see When Firefight asks first.

A connection made with a service token and no id cannot reach the API, so you add a webhook to each database you want followed. The connection’s details under Integrations show the address to send changes to, the steps, the events to select, and a Signing secret field. Until a secret is saved the connection shows Live updates: off and the map updates every hour.

  1. In PlanetScale, open a database, then Settings → Webhooks, and choose Add webhook.
  2. Paste the address from Firefight as the URL, and select the events listed in Firefight.
  3. Save the webhook, choose Show secret from its menu, paste the secret into Firefight and press Add secret.
  4. Do the same for each database you want followed.

Each database’s webhook has a secret of its own, so the field keeps every secret you add, and a change signed with any of them reaches the map. PlanetScale allows five webhooks per database, and Firefight’s takes one. Forget secrets removes all of them after you confirm, for example when you replace your webhooks. Changes then stop reaching the map until you add a secret again. PlanetScale sends deploy request events for Vitess databases only.

A deploy request moving has Halon check the watches reading through the connection at once, and one that applied its schema or stopped on an error starts any workflow whose trigger is Deploy or CI finished.

Supabase also connects through its own MCP server, and sends changes through Platform Webhooks, which are in early access. Supabase turns away organizations outside its early access list, and their projects update every hour. The connection’s details under Integrations show the address, the steps and the event types to send.

  1. Choose a signing secret of 8 to 64 characters.
  2. With a Supabase personal access token, create an endpoint through Supabase’s Management API, with POST https://api.supabase.com/v2/organizations/<organization slug>/webhooks/endpoints for every project in an organization, or /v2/projects/<project ref>/webhooks/endpoints for one project.
  3. Give it the address from Firefight as its url, your signing secret, and the event types listed in Firefight.
  4. Do the same for each organization the connection reaches, with the same secret, then paste the secret into Signing secret in Firefight and press Save secret.

Saving a new secret for Supabase replaces the one before.

For both PlanetScale and Supabase, Firefight accepts a change only when it is signed with a secret you saved or one PlanetScale gave Firefight for its own webhook, and it never shows a saved secret again. Keep the tools that read a database and a branch on PlanetScale, or a project and its branches on Supabase, switched on for the connection. With them off, a change takes longer to reach the map.

Firefight reads the CloudTrail event history of every region an AWS connection reads, every 5 minutes. A change made in the AWS console, with the AWS CLI or by a deploy tool reaches the map within about ten minutes. The access key needs cloudtrail:LookupEvents, which the connect form asks for. Without it the connection shows Live updates: off with what AWS answered, and the map still updates every hour.

ResourceWhat brings an update
ECS servicesA service created, updated (a deploy, a new task count), deleted or tagged
Lambda functionsA function created, its code or configuration updated, a version published, an alias moved, deleted or tagged
EC2 instancesAn instance launched, started, stopped, terminated, changed or tagged
RDS databasesA database created, restored, changed, rebooted, started, stopped, promoted, deleted or tagged
CodeBuild projectsA project created, updated or deleted
CodePipeline pipelinesA pipeline created, changed or deleted, and an execution started, stopped, retried or rolled back
CodeDeploy deployment groupsA group created, changed or deleted, and a deployment started
CloudFormation stacksA stack created, updated, deleted, a change set run, and an update cancelled or continued
App Runner servicesA service created, updated, deleted, paused or resumed, and a deployment started
Elastic Beanstalk environmentsAn environment created, updated, rebuilt or terminated, and its app server restarted

An ECS deployment finishing is not in CloudTrail. In a region without the stack below, Firefight asks ECS about each service whose deployment started until it has finished, then reads the service again, so a deploy’s end reaches the map and a watch on it within about 10 minutes.

To get AWS’s changes as they happen, open the AWS connection’s details under Integrations and find Get changes instantly, which lists each region the connection reads. Choose Create stack beside a region. AWS’s CloudFormation console opens in that region with Firefight’s template, the connection’s address and its key already filled in. Tick the box that acknowledges the stack creates an IAM role, then choose Create stack.

The stack sends Firefight these, as they happen:

  • EC2 instances changing state, ECS service events and deployments, and RDS database events
  • CodeBuild builds and their phases starting and ending, so a watch on a build hears at once
  • Pipeline executions, stages and actions changing state, CodeDeploy deployments changing state, App Runner operations and services changing status, and Elastic Beanstalk environments changing status or health
  • Your other CloudFormation stacks changing status
  • The changes in the table above, while the account has a CloudTrail trail that is logging

A stack created before CodeBuild projects, pipelines, deployments, stacks, App Runner and Elastic Beanstalk joined sends only what it was made with, and those changes keep arriving every 5 minutes. To have them sent as they happen too, delete that region’s firefight-live-updates- stack in CloudFormation. Once it is gone the region’s row offers Create stack again, and the new stack sends everything above. The same goes for a stack created before Lambda versions and aliases joined, which keeps sending those every 5 minutes until you create it again.

Lambda has no state changes of its own to send, so in an account without a trail, Lambda changes keep arriving every 5 minutes. Once a region sends its first change, its row says Sending with when Firefight last heard from it. Live updates stay on while either way works. If Firefight cannot read CloudTrail but a region sends changes, the reason says so and names the regions still sending.

A few regions do not offer what the stack needs: Melbourne, Taipei, Malaysia, New Zealand, Thailand, Calgary, Tel Aviv, Mexico and both AWS GovCloud (US) regions. Their rows say so, and their changes arrive every 5 minutes. In Beijing and Ningxia the stack is created in the China console, from Firefight’s template published in China. Until that template is published, their rows say so and their changes arrive every 5 minutes.

Firefight did not create the stack, so it cannot remove it. To stop, delete the stack in CloudFormation in each region you created it in. Its name, starting with firefight-live-updates-, is shown under Get changes instantly. Removing the AWS connection in Firefight stops accepting what the stack sends straight away, and the message that confirms it names the stack and the regions to delete it from.

Connections Firefight checks on a schedule

Section titled “Connections Firefight checks on a schedule”

These send no updates Firefight can sign up for, so Firefight checks each of them on a schedule and reads again whatever changed. Firefight adds nothing to your account, and each needs a little access:

  • Cloudflare reads the audit log through Cloudflare’s own server, with execute, so execute has to be switched on for the connection. Reading the audit log also needs the Account Settings Read permission. Without either, live updates are off with the reason, and Cloudflare is read once a day.
  • Kubernetes needs the service account’s role to allow watch on the same deployments, statefulsets, daemonsets, cronjobs, jobs, services and ingresses it can already get and list. Without it, live updates are off and the reason names what the role may not watch. With watch on events too, a Warning event about a workload, such as a pod failing to pull its image, reaches Halon’s watches on it. Without that, everything else still updates.
  • Fly.io needs nothing more. An organization with many apps takes longer to check, and in one with more than 240 apps a change can take longer than 6 minutes to reach the map.
  • Neon needs the list_operations tool switched on for the connection. If Neon’s server does not offer that tool, live updates are off with the reason, and Neon is read every hour.
  • ClickHouse needs the get_organizations and get_services_list tools switched on for the connection. ClickPipes are followed only while list_clickpipes is on.
  • DigitalOcean and Modal need nothing more. Firefight reads each DigitalOcean app’s events, and lists the Modal environment’s apps, every 5 minutes.

Every check through Cloudflare’s, Neon’s or ClickHouse’s server appears in Activity under the Map sweep source.

A Pages build that starts from a push is not in Cloudflare’s audit log. To have Halon hear about Pages deployments as they happen, send Cloudflare’s Pages notification to Firefight. The Cloudflare connection’s details under Integrations show the address, the steps and a Signing secret field.

  1. Choose a long random secret, paste it into Signing secret in Firefight and press Save secret. Saving it first lets Cloudflare’s test reach Firefight.
  2. In the Cloudflare dashboard, go to Alerts, then Destinations, and under Webhooks choose Create.
  3. Paste the address from Firefight as the URL and the same secret as its Secret, then choose Save and Test.
  4. Go to Alerts, then Overview, and choose Create an Alert. Pick Pages, Project updates, choose the projects and the Deployment started, Deployment failed and Deployment success events, and add that webhook as its destination.
  5. Do the same for each Cloudflare account the connection reaches, with the same secret.

A Pages notification changes nothing on the map. It makes Halon check the deployments it is watching straight away.

Firefight follows a Convex deployment through a log stream that sends Convex’s audit log to Firefight, and nothing else from the deployment. Convex lets a deployment send to one webhook log stream, and log streams are not on every Convex account. So Firefight does not add its own on its own. The connection shows Live updates: off with what adding it would mean, and a Turn on button, see When Firefight asks first. Adding and removing the log stream appear in Activity under the Map sweep source.

When the deployment already sends a webhook log stream of yours, Convex turns Firefight’s down, and the connection says so under Live updates: off. Firefight tries again once a day.

Trigger.dev cannot add an alert through its API, so you add a webhook alert yourself. The connection’s details under Integrations show the address to send alerts to, the steps, and a Signing secret field. Until a secret is saved the connection shows Live updates: off and the map updates every hour.

  1. In Trigger.dev, open the project and environment the connection reads, then Alerts, and choose New alert.
  2. Choose Webhook, and paste the address from Firefight as its URL.
  3. Select Run fails, Deployment fails and Deployment succeeds, then save the alert.
  4. Copy the secret Trigger.dev shows for the webhook, paste it into Signing secret in Firefight and press Add secret.
  5. To hear of error groups too, open Errors, choose Configure alerts, add a webhook with the same address, and add its secret in Firefight the same way.

Each alert has a secret of its own, so the field keeps every secret you add, and an alert signed with any of them is accepted. A deployment that succeeds updates the environment’s tasks on the map. A deployment that succeeds or fails also starts any workflow whose trigger is Deploy or CI finished. Forget secrets removes all of them after you confirm.

Firefight reads the activity log of every subscription an Azure connection reads, every 5 minutes, with the access the connection already has. A change reaches the map within about 25 minutes, since Azure adds a change to its activity log 3 to 20 minutes after it happens.

To get Azure’s changes as they happen, open the Azure connection’s details under Integrations and choose Turn on under live updates. Firefight then subscribes the connection to each subscription’s resource changes through Azure Event Grid, and Azure makes an Event Grid system topic in the subscription to send them. A change then reaches the map within about a minute, and a watch on it hears at once. The activity log is still read every 5 minutes, so a change Event Grid misses still arrives.

Event Grid needs two things the connection was not asked for:

  • The service principal needs the EventGrid EventSubscription Contributor role on each subscription it reads.
  • Microsoft.EventGrid must be registered as a resource provider on each subscription. In the Azure portal, open the subscription, then Resource providers, and register it.

Pressing Turn on says this again before anything changes. When something is missing, Firefight names the subscription and what it lacks, and the activity log keeps working. Give the access, then press Turn on again. A subscription the connection reads later is subscribed at the next hourly read, with the same access.

Turn off removes Firefight’s Event Grid subscription, and Azure removes the system topic it made for it. The activity log is still read every 5 minutes, so the connection still shows live updates as on. Adding and removing the subscription appear in Activity under the Map sweep source.

Key checks are the first readings worth taking on a resource, such as a service’s error rate and p95 latency. Open a resource in Focus to see its checks under Key checks, each with the connection it reads from and what is normal for it over the last week, such as “usually 80 ms, 95% under 133 ms”.

KindKey checks
ServiceError rate, p95 latency, CPU, memory, recent deploys
WorkerError rate, CPU, memory, recent deploys
JobHow it stands, errors, CPU, memory, recent deploys
FunctionInvocations, errors, duration, throttles
DatabaseCPU, memory, connections, disk
Database branchHow it stands, CPU, memory, connections, disk
Virtual machineHow it stands, CPU, memory, disk
ComputeHow it stands, CPU, memory
ClusterHow it stands
DomainAvailability
Static siteAvailability, recent deploys
ZoneAvailability, traffic, error rate
RepositoryCI status, recent deploys
QueueRecent errors

Buckets, key value stores, database proxies, tunnels, load balancers, origin pools, access policies and build services have no key checks, and their panel says why. Error rate reads 5xx responses, or errors where a provider counts no responses, and the check says which it reads.

Choose Run to take the reading now. The answer appears under the check with its chart and a line saying how it compares with normal, such as “Now 412 ms, 3.1x the usual high of 133 ms”. A check runs as you, through the connection’s own tool, so it needs the same permission, waits for the same approval rules and shows in Activity under that tool. Without the permission, Run stays visible but inactive, and its tooltip names what to ask an admin for. When a call needs approval, the check says so, and you run it again once someone approves it.

A check that cannot run here says why, such as the connection’s tool being switched off under Integrations, or the provider not keeping that reading for the resource. Switching the tool on brings the check back straight away.

Firefight learns the kinds of line each important resource usually logs, so a line seen during an incident can be told apart from one that was there all week. Open a resource in Focus to see the ten it prints most under Usual log lines, each with how many lines followed it in the last read and how many daily reads saw it. Error and warning lines are marked.

Once a day Firefight reads a sample of logs from across the last week. It reads these resources, up to 200 a connection each day:

  • Services, workers, jobs and functions linked to a catalog entry
  • Resources whose catalog services had an incident in the last 90 days
  • The 50 resources most others depend on

Before anything is kept, Firefight removes anything that looks like a credential, then replaces times, numbers, ids, email addresses, IP addresses, query strings and quoted values with placeholders, such as GET /orders/<NUM> <NUM> in <NUM> ms. Only these patterns are kept, never the lines, and a pattern no read has seen for a week is dropped. The reads use the connection’s logs tool, which must be switched on under Integrations, and appear in Activity under the Map sweep source.

A resource with no usual log lines says why, such as its logs tool being switched off, it not being among the resources Firefight reads, or it not being read yet. Linking it to the catalog entry it runs brings a service into the daily read.

Press Ctrl K, or ⌘K on a Mac, on any dashboard page, or choose Search at the top of the page, to search the map, the catalog and what Halon remembers in one place. On the chat page the shortcut searches your chats instead, so use the Search button there.

Type any of these:

  • A name or a provider’s id, such as payments-db or an AWS ARN. An exact match always comes first.
  • Part of a name, or one with a typo, such as paym or ledgr.
  • A tag, such as team=payments, or either half of it.
  • A team, to find what it owns, or a catalog service, to find what it runs on.
  • What a service does, such as sends receipts. A catalog entry with a description is found by what its description means, not only by its words, when Halon is turned on for your workspace.

Results from the map, the catalog and confirmed memories are ranked together, best first. Each says where it lives, such as a database on Northflank in Production, and why it matched, such as its name or a team that owns it. The best 25 are shown, so add a word to narrow a long list.

Choosing a result opens it:

ResultOpens
A resourceThe map in Focus on that resource
A catalog entryIts catalog type, with the entry open
A memoryThe Memory page, with that memory marked

Searching needs permission to read the map, and only shows what you can see. Approval rules never hold a search, since it only reads. Resources come from the environments you can read on the map, catalog entries need permission to read the catalog, and memories need Halon to be turned on and permission to read memory. Only memories someone confirmed are searched.

Reading the map is its own permission, Resource Map. Members see the whole map in every environment without a grant, and admins and owners always do. An admin can limit a member to some environments by granting them Resource Map scoped to those environments, and from then on the map, the search and the map tools show them only what runs there. The map then says which environments it is showing, and that an admin decides which ones you see. Agents and service keys read the map only once they are granted Resource Map. See Permissions for how to grant it.

What you can do on the map follows your other permissions. Sync now needs permission to manage integrations, and adding, removing, confirming or dismissing links and linking catalog entries need permission to change the catalog.

Halon reads and searches the map when you ask it about your infrastructure, so it knows what runs where without listing each provider again, and it can suggest a link it finds evidence for. Agents you connect over the MCP server have the same tools:

ToolWhat it does
get_resource_mapThe whole map one line per resource, or one resource’s fact sheet with its links within two hops, its key checks and the log lines it usually prints
search_mapOne search across the map, the catalog and confirmed memories, the same as the dashboard’s search
find_resourcesResources by provider, kind, account, environment, status, owning team, catalog service or recent change, a page at a time
get_resourceOne resource’s details, its catalog services, its normal readings and key checks, and how many links lead in and out
get_resource_linksThe links into and out of one resource, each with how it was found
get_resource_neighboursThe resources one link away, both ways
traverse_resource_mapA walk from one resource toward what it depends on or what depends on it, up to several links away
blast_radiusWhat fails with a resource, counted by kind, provider and environment, with the catalog services and open incidents it reaches
resource_map_statsThe map in numbers, with each connection’s last read and what it could not read
suggest_resource_linkSuggests a link between two resources with the evidence for it. It shows under To review until someone confirms or dismisses it
run_key_queryRuns one of a resource’s key checks and says how the reading compares with normal
new_log_patternsReads a resource’s recent logs and answers which kinds of line it did not print in the last week, and which of its error lines are usual

Each link the tools read names the settings it came from, never their values. Only what runs in the environments the caller may read is found or counted. Suggesting a link needs permission to change the catalog, and run_key_query and new_log_patterns need the same permission as the connection’s own tool and show in Activity under it. Halon does not blame a log line the resource printed all week unless something shows it changed, such as a new pattern, a reading above normal or a deploy.