Skip to main content

PostgreSQL schema evolution with built-in multi-agent coordination 🍓

Project description

Confiture 🍓

PostgreSQL migrations, sweetly done.

Build from DDL. Adopt on day one against a database that already has migrations applied. Preflight every deploy against a parallel database with structural diff. Sync production data with PII anonymization.

PyPI Quality Gate Python 3.11+ PostgreSQL 12+ License: MIT


In 30 seconds

# 1. You already have a database at migration 004 (applied by hand or by another tool).
#    Tell Confiture about that history without re-running the SQL:
$ confiture migrate baseline --through 004 -c db/environments/production.yaml
   001 create_users (marked as applied)
   002 create_orders (marked as applied)
   003 add_user_email (marked as applied)
   004 add_user_preferences (marked as applied) Marked 4 migration(s) as applied, skipped 0 already applied

# 2. Machine-readable proof that the tracking is healthy:
$ confiture migrate status -c db/environments/production.yaml --format json | jq '.applied | length'
4

# 3. Preflight: replay pending migrations on a parallel DB, emit a structural diff vs. db/schema/.
$ confiture migrate preflight --against "$PREFLIGHT_URL" -c db/environments/production.yaml
▸ Replaying pending migrations on preflight DB    20260520143015_add_user_bio                 applied in 24 ms
▸ Comparing resulting schema vs. db/schema/    No drift  preflight matches db/schema/
✓ Preflight passed. Safe to deploy.
exit 0

That's the loop. Baseline once → status to confirm → preflight every deploy.


Already have migrations?

The single biggest reason migration tools fail adoption is the day-one cliff: existing tables already exist, so any tool that tries to apply migrations from scratch crashes on the first CREATE TABLE. Confiture's answer is migrate baseline:

confiture migrate baseline --through <last-applied-version>

The walkthrough — including failure modes, the integration test that backs the recipe, and what tb_confiture ends up looking like — is in docs/guides/legacy-bootstrap.md.


No db/schema/ directory? That works too.

confiture migrate up, down, down-to, status, current, baseline, and preflight are the migration runner — they don't require a db/schema/ directory (migrate current prints the latest applied revision as a narrow "what's deployed?" contract; migrate down --steps N rolls back relatively while migrate down-to <revision> rolls back to a specific revision, refusing atomically if any required .down.sql is missing). The "Build from DDL" pitch above the fold sells one of confiture's four strategies; the other three (incremental migrations, production sync, schema-to-schema FDW migration) work against a project whose only source of truth is the migration chain itself.

If you're evaluating confiture against Flyway / Alembic / dbmate / sqlx-cli as a pure migration runner, skip confiture build and use everything else. Walkthrough: docs/guides/02-incremental-migrations.md.


When to use Confiture?

Capability Confiture Flyway Alembic dbmate sqlx-cli plain psql
Source of truth DDL files or migration chain migration chain model classes migration chain migration chain DDL files
Tracking table yes yes yes yes yes no
Rollback (down.sql) yes paid yes yes yes no
Preflight against a copy DB yes (structural diff) no no no no no
Build from scratch in <1s yes no no no no yes (manual)
Production sync + anonymization yes no no no no no
Zero-downtime via FDW yes no no no no no
Multi-agent coordination yes no no no no no
Ecosystem maturity / stars early very mature mature mature mature n/a

Note on "source of truth": confiture can run as a pure migration tool against a project that has no db/schema/ directory — the DDL workflow is opt-in. See No db/schema/ directory? above.

Confiture wins on build-from-DDL, structural-diff preflight, production sync, and multi-agent coordination. It loses on ecosystem age — Flyway and Alembic have a decade of community knowledge. Pick honestly.

Adoption checklist

Situation Recommended tool
1 environment + 1 contributor, schema rarely changes plain psql
2+ environments, schema changes weekly Confiture, Flyway, Alembic, or dbmate
Multi-agent / AI-driven development on shared schemas Confiture
You have a migration chain (no db/schema/) and want preflight + tracking Confiture (use everything except confiture build)
You want db/schema/ to be source of truth, not a migration chain Confiture
You need zero-downtime schema swaps with postgres_fdw Confiture (Medium 4)
You're committed to SQLAlchemy ORM Alembic
You're committed to a JVM stack Flyway

CI integration

A migrate preflight gate on every PR, a migrate up step on deploy. Exit codes are semantic, so the CI configuration stays simple:

# .github/workflows/db.yml
name: DB

on:
  pull_request:
    paths:
      - 'db/**'
  push:
    branches: [main]

jobs:
  preflight:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env: { POSTGRES_PASSWORD: x }
        ports: ['5432:5432']
        options: >-
          --health-cmd pg_isready --health-interval 10s
          --health-timeout 5s --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v3
      - run: uv pip install --system "fraiseql-confiture[ast]"
      - name: Restore production snapshot to preflight DB
        run: ./scripts/restore-snapshot.sh   # your own; pg_restore from S3/GCS
      - name: Confiture preflight
        env:
          PREFLIGHT_URL: postgresql://postgres:x@localhost:5432/preflight
        run: |
          confiture migrate preflight \
            --against "$PREFLIGHT_URL" \
            -c db/environments/preflight.yaml \
            --format json --output preflight.json
      - uses: actions/upload-artifact@v4
        with:
          name: preflight-report
          path: preflight.json

  deploy:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v3
      - run: uv pip install --system "fraiseql-confiture[ast]"
      # No YAML needed in CI — the migrate family reads DATABASE_URL directly
      # (or pass --database-url "$DSN"). See the connection-source docs below.
      - run: confiture migrate up
        env:
          DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}

migrate up/down/status/verify/preflight accept --database-url <dsn> (or read CONFITURE_DATABASE_URL / DATABASE_URL) so runtime-resolved DSNs need no temp YAML — precedence and details in the CLI reference.

Exit codes are a documented stability contract — see the exit-code reference. The most operationally important: 2 tracking table absent, 3 DB connection failed, 5 config invalid, 6 lock contention. For migrate preflight's drift-gate codes specifically, see the dry-run guide.

Migrations that open their own SAVEPOINTs, use psycopg's conn.transaction(), or wrap DO $$ … EXCEPTION WHEN … $$ blocks are supported under all three modes. The rules a migration body must follow for the SAVEPOINT-based rollback to stay clean are documented in the transaction & SAVEPOINT contract.


Python project snippet

Add Confiture as a dev dependency. The [ast] extra pulls in pglast for full PostgreSQL parsing — recommended for schemas with bulk seed data.

# pyproject.toml
[dependency-groups]
dev = [
  "fraiseql-confiture[ast]>=0.9",
  "pytest>=8",
]
# justfile
default:
    just --list

db-build:
    confiture build --env local

db-up:
    confiture migrate up

db-status:
    confiture migrate status

db-preflight:
    confiture migrate preflight --against "$PREFLIGHT_URL"

Or as a Makefile:

db-build:
	confiture build --env local

db-up:
	confiture migrate up

db-status:
	confiture migrate status

Library API

Confiture is a CLI first, but the migrator is fully usable from Python:

from confiture import Migrator

with Migrator.from_config("db/environments/prod.yaml") as m:
    status = m.status()
    if status.has_pending:
        result = m.up()
        print(f"Applied {len(result.applied)} migrations")

The Four Strategies

Strategy Use Case Command
Build from DDL Fresh databases, testing, CI confiture build --env local
Incremental Migrations Existing databases, production confiture migrate up
Production Sync Copy data with PII anonymization confiture sync --from prod --anonymize users.email
Zero-Downtime Complex migrations via FDW confiture migrate schema-to-schema

Documentation

Start here

Guides

Reference

For agents and tooling

  • Every machine-readable CLI output has a published JSON schema under docs/reference/json-schemas/ — see docs/reference/json-schemas.md.
  • On an error path in --format json mode, the migrate family emits a structured error envelope on stdout — {"ok": false, "error": {code, message, severity, actionable, details, migration, file, line}} — and exits with the exit code for that error. The full code list and the envelope schema are in the error-code codebook.
  • confiture migrate validate --list-patterns --format json exposes the full idempotency-detection catalog (read-only, no DB / config / migrations directory needed).
  • Quiet-success ambiguities surface advisory hints in payload["hints"] (or on stderr in text mode) — exit codes are unaffected.

Contributing

git clone https://github.com/fraiseql/confiture.git
cd confiture
uv sync --all-extras
uv run pytest

See CONTRIBUTING.md and CLAUDE.md.


Author & License

Vibe-engineered by Lionel Hamayon 🍓

MIT License — Copyright (c) 2025 Lionel Hamayon


Making jam from strawberries, one migration at a time. 🍓→🍯

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fraiseql_confiture-0.37.0.tar.gz (2.1 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fraiseql_confiture-0.37.0-cp314-cp314-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.14Windows x86-64

fraiseql_confiture-0.37.0-cp313-cp313-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.13Windows x86-64

fraiseql_confiture-0.37.0-cp313-cp313-manylinux_2_28_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

fraiseql_confiture-0.37.0-cp313-cp313-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

fraiseql_confiture-0.37.0-cp312-cp312-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.12Windows x86-64

fraiseql_confiture-0.37.0-cp312-cp312-manylinux_2_28_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

fraiseql_confiture-0.37.0-cp312-cp312-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

fraiseql_confiture-0.37.0-cp311-cp311-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.11Windows x86-64

fraiseql_confiture-0.37.0-cp311-cp311-manylinux_2_28_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

fraiseql_confiture-0.37.0-cp311-cp311-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file fraiseql_confiture-0.37.0.tar.gz.

File metadata

  • Download URL: fraiseql_confiture-0.37.0.tar.gz
  • Upload date:
  • Size: 2.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0.tar.gz
Algorithm Hash digest
SHA256 fa2e719479a3b7015d9c708e89df386aa751052841a90284e5bdd5e0c938896b
MD5 141359c758b2ea5e042f2d2951ee29c9
BLAKE2b-256 1629169862932641302893c36d7e8b014b0fbc2c2d2a67a8fd24cf59d9fd2e5c

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 e0464152dca10ea79dca6e286484836932bb5572a543742baf44c27bb33a74c6
MD5 155c513dfa429f407aebb460ed378759
BLAKE2b-256 f40773d1492939bb7f9daf3725cd154a2a89227f68882ef93d2ba74d9e477c11

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 7a869b4db5862b4a92e4bfd665cc3cdc3eca082479cef553d3f252e9e581a3a9
MD5 5de5bfefaed9236a81a8047b4ea005aa
BLAKE2b-256 8b544b3db7de4deb569574f45388edfd14d96207f51b88f3a74102bafd10d4fd

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp313-cp313-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.13, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 38308df8758bfc14177c93c429bd8abad7db53edc7afbae9fc9bc7960109bc99
MD5 e8275d006be439d99edb34bef2c217cd
BLAKE2b-256 71e4601161ea596d6b3f2ffce2bfb2b81b71d83ca1d0b35bb9d175969a7fd797

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp313-cp313-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.13, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3a9162aaf0295198ffeafbde220c87850a16e8a3681e3383fc1903c52637e649
MD5 2ec820ba4cc1216719937fb2f2d3c2c0
BLAKE2b-256 d67ce54343efc49a0603ddc82e18a95f144846b6da99ff11c0531e45b351ae11

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e97341a9a5bb50a9adc21b984d4e262d6c5eea0777da18a3c1b432ba67f56476
MD5 eb10ddd581c257f1e9b0b5a9a67f91e7
BLAKE2b-256 bdc55b57998fd17b6d04ce87b40e59a034de7ec66125038722f9f75336aad888

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp312-cp312-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3da2ad5ce4f03910da52ecab8c4466ad63cdc268194267eeb55ef7a1f39e320b
MD5 a93db62af9667d0b850cc51aa6b36716
BLAKE2b-256 21afb5381f3d72c2145e7292e4e5e9c5ebaee6605dabba607ad386b11ccbcd5f

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp312-cp312-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.12, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 106a8c3030efd10306118eba196a5c513a2d902f48509ebacf456dfc0eefb6b7
MD5 8a594421bb63f4084a84b215f543c75f
BLAKE2b-256 028e02f899873289afa346646290f890ea68134e1298bfab152e2da2ab765697

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 05e15b1d61637a270242261fb7528c49dd0f081bb6e52050239f1db889d791c3
MD5 4fc1e71f649ca20553e3ac07ed76c611
BLAKE2b-256 737cd1aefd1f5bf415111f2337a97ba099285cc8c68db9b4a143c4780ed89366

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp311-cp311-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6a277685cff53df9b8d9af6c7e4c9f99a53cff54dcab5b7159b3b4b9b9809ab5
MD5 c276536f834460b8522f326f85579822
BLAKE2b-256 e246cc4e81a385d406eab009ec1eba4792e5e0cfffe72bf1d267b12d751de809

See more details on using hashes here.

File details

Details for the file fraiseql_confiture-0.37.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

  • Download URL: fraiseql_confiture-0.37.0-cp311-cp311-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.11, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fraiseql_confiture-0.37.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 82142bb60594b9b78bd7d07f9e2879deb61b17a52cb4c333db980ae1cbe7e0c5
MD5 79fe210a23781e68ee0261517ed983f2
BLAKE2b-256 759935a3b64b887a328346bb2c977f8538d15ef9161b2b5ba0cb6d306f4a1e43

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page