Azpg when not to use
Skill lestermarch/postgres-ai-experts/skills/azpg-when-not-to-use
Composable AI agents and skills for operating Azure Database for PostgreSQL Flexible Server - PostgreSQL can be used for everything.
npx -y skills add lestermarch/postgres-ai-experts --skill azpg-when-not-to-useAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
3 things to look at
- 23 days oldThe repository was created 23 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
The devil's-advocate / right-tool advisor for Azure Database for PostgreSQL Flexible Server. Use this skill whenever someone asks "should this live in Postgres?", is weighing Postgres against a dedicated Azure service, is hitting a scaling wall, or is about to force a workload (messaging, global distribution, extreme-low-latency cache, full-text/vector search at massive scale, heavy analytics/OLAP, large blobs, high-ingest time-series) onto Postgres because "PostgreSQL can do everything." Deliberately argues AGAINST the single-platform premise where the evidence warrants, giving break-out thresholds, the signals to watch, and the specific Azure service to reach for — and, just as importantly, when to stay put. Reach for this before over-engineer ing a Postgres workaround or prematurely breaking a workload out.
SKILL.md
9.6 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it
When NOT to use Postgres (right-tool advisor)
This repo's premise is "PostgreSQL can be used for everything." This skill is the honest counterweight: it argues against the premise when the evidence warrants, so teams don't paint themselves into a corner by forcing the wrong workload onto Flexible Server — or, equally, don't prematurely abandon Postgres for a shiny dedicated service they don't yet need.
This skill is read-only and advisory. It inspects scale signals and gives a recommendation with trade-offs; it never changes anything. There is no write path.
The goal is a defensible recommendation, not dogma. Most workloads should stay in Postgres far longer than people assume — extensions (
pgvector,pgmq, JSONB, PostGIS, full-text) push the break-out line out a long way. Only recommend breaking out when a concrete signal crosses a real limit. Deep per-domain thresholds are inreference.md; the hard Flexible Server ceilings that anchor the thresholds are inazure-constraints.md.
Live instance context (dynamic injection)
Ground the advice in the workload's actual scale before quoting any threshold —
a recommendation to break out (or stay) is only credible against real numbers.
PGCONN is a libpq connection string. These are read-only and safe to
auto-run.
- Database size (how close to the storage ceiling?):
!
psql "$PGCONN" -tAc "SELECT pg_size_pretty(pg_database_size(current_database()));" 2>/dev/null || echo "(could not connect — ask for connection details)" - Largest tables (where the pressure actually is):
!
psql "$PGCONN" -tAc "SELECT relname, pg_size_pretty(pg_total_relation_size(relid)) AS total, n_live_tup FROM pg_stat_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 8;" 2>/dev/null || echo "(unknown)" - Connection pressure (used vs ceiling):
!
psql "$PGCONN" -tAc "SELECT count(*) AS conns, current_setting('max_connections') AS max FROM pg_stat_activity;" 2>/dev/null || echo "(unknown)" - Which single-platform extensions are already carrying load:
!
psql "$PGCONN" -tAc "SELECT extname FROM pg_extension WHERE extname IN ('pgmq','vector','pg_diskann','postgis','pg_cron','timescaledb') ORDER BY extname;" 2>/dev/null || echo "(none)"
If injection is unavailable, run
scripts/scale_signals.sql and read its output.
Never quote a break-out threshold without a real number next to it.
When to use this skill
Trigger on: "should we use Postgres for X?", "is Postgres the right choice for a queue / cache / search / analytics / global app?", "we're hitting a wall on size/connections/latency", "should we move this to Cosmos DB / Event Hubs / AI Search / Redis / Fabric?", or any moment where the single-platform premise is about to be stretched. Also use it defensively — when someone wants to break out but the numbers say Postgres is fine, say so.
How to give a recommendation
- Get the real numbers (injection above). Size, hottest tables, connection pressure, and which extensions already run. No numbers → no verdict.
- Identify the workload class — messaging, search/vector, global distribution, cache, analytics/OLAP, time-series, or blob/large-object.
- Compare against the break-out signal for that class (table below +
reference.md). A break-out is warranted only when a concrete signal crosses a real limit, not on vibes. - State the trade-off both ways. What you gain by breaking out (and what you
lose: transactional consistency, one system to operate,
JOINs across the data). What you gain by staying (simplicity) and what you risk. - Recommend the specific Azure service if breaking out, and how to integrate (often alongside Postgres, not instead of it).
Break-out signals by workload class (summary)
Stay in Postgres until the break-out signal fires; then reach for the service
named. Full thresholds, trade-offs, and integration notes in
reference.md.
| Workload | Stay in Postgres with… | Break-out signal | Reach for |
|---|---|---|---|
| Queue / jobs | pgmq, SELECT … FOR UPDATE SKIP LOCKED | Millions of msgs/sec, fan-out to many consumers, cross-region eventing | Service Bus / Event Hubs |
| Search / vector | pgvector (+ DiskANN), full-text tsvector | ≫100M vectors, heavy relevance tuning, hybrid ranking at scale | Azure AI Search |
| Global distribution | Read replicas, JSONB | Multi-region active-active writes, single-digit-ms global reads | Cosmos DB |
| Cache | UNLOGGED tables, in-DB memoisation | Sub-ms p99 at very high QPS as a dedicated cache | Azure Managed Redis |
| Analytics / OLAP | Columnar-ish patterns, materialised views, read replica | TB-scale scans, star schemas, BI concurrency hurting OLTP | Microsoft Fabric / Synapse |
| Time-series | Partitioning, BRIN, pg_cron rollups | Extreme sustained ingest + retention beyond storage ceiling | Azure Data Explorer |
| Large blobs | bytea / large objects for small files | Files > a few MB, media, many-GB objects | Azure Blob Storage (store URL in PG) |
| In-DB LLM generation | azure_ai.generate on a non-reasoning model | Only reasoning models (gpt-5/o-series) deployable, or you need generation params (temperature, tools, JSON mode) azure_ai.generate doesn't expose | App-tier call to Azure OpenAI (keep embeddings + retrieval in PG) |
The strongest pattern is usually Postgres as the system of record + a break-out service alongside it, not a wholesale migration.
Read / inspect steps (safe · auto)
Everything this skill does is read-only:
- Scale signals —
scripts/scale_signals.sqlgathers DB size, top tables, connection pressure, and extension presence in one pass (the injection backstop). - Confirm the wall is real — before recommending a break-out on a performance
complaint, verify the workload is actually saturated, not just un-tuned. A slow
query is often an index or config problem, not a platform problem — route to
azpg-explain-analyze/azpg-index-selection/azpg-config-tuningfirst.
Common false alarms (stay in Postgres)
Push back on premature break-out when the real fix is cheaper:
- "Postgres can't handle our queue."
pgmq+SKIP LOCKEDhandles very high throughput. Break out for cross-region eventing or massive fan-out, not for a few thousand jobs/sec. →azpg-ai-in-database/ messaging skills. - "We need Redis for caching."
UNLOGGEDtables and app-side caching cover many cases without another system. Break out for a dedicated sub-ms cache at high QPS. - "Vector search won't scale."
pgvector+ DiskANN scales to many millions of vectors. Break out to AI Search for ≫100M vectors or heavy hybrid relevance. →azpg-pgvector-rag. - "The database is slow, we've outgrown Postgres." Usually tuning, indexing,
or a bad plan — verify with
azpg-explain-analyzebefore blaming the platform.
A worked "should we break out?" decision, end to end, is in
examples/breakout_decision.md.
Advisory protocol
- Numbers before verdict. Never recommend break-out or stay-put without the real scale signals in hand.
- Rule out tuning first. Performance complaints route to
azpg-explain-analyze/azpg-index-selection/azpg-config-tuningbefore any platform verdict. - State both sides. Every recommendation names what's gained and lost — a break-out costs you transactional consistency and one-system simplicity.
- Prefer "alongside," not "instead of." The default shape is Postgres as system of record with a specialised service for the one dimension it can't serve — keep the blast radius small.
- Read-only, always. This skill never provisions or migrates. If the verdict
is "break out," hand off (e.g.
azpg-provision-iacfor a new component, migration skills for a move) — don't act here.
Bundled files
reference.md— per-workload break-out thresholds, the signals to watch, trade-offs, and which Azure service + integration pattern to use.azure-constraints.md— the hard Flexible Server ceilings (storage, connections, single-region writes, IOPS) that anchor the thresholds.scripts/scale_signals.sql— read-only signal gatherer (injection backstop).examples/breakout_decision.md— a worked decision with real numbers and a both-sides recommendation.
What ships with it: 6 files
24.6 KB alongside SKILL.md
examples/
- breakout_decision.md4.3 KB
scripts/
- README.md1.2 KB
- scale_signals.sql2.4 KB
- azure-constraints.md3.8 KB
- EVALUATION.md4.9 KB
- reference.md8.0 KB