# PostgreSQL JSONB Size Limits: The `256MB` Cap, TOAST Storage, and Indexing Pitfalls

PostgreSQL enforces a strict `268,435,455-byte` (approximately 256 megabytes) limit on individual JSONB values, determined by internal 28-bit length masks in the varlena container header. While generic text fields can expand to 1 gigabyte via TOAST, large JSONB trees suffer from severe GIN index degradation and write amplification. Architectures managing massive document payloads or agentic workflows must understand these storage mechanics and consider external intelligent storage layers.

Source: https://fast.io/resources/postgres-jsonb-size-limit/
Author: [Derek Labian](https://fast.io/authors/derek-labian/)
Last reviewed: 2026-10-08

## Why PostgreSQL Caps JSONB at 268,435,455 Bytes: Varlena Headers and Container Limits

The PostgreSQL JSONB size limit is a hard cap of `268,435,455 bytes` (approximately 256 megabytes) on any single jsonb value, determined by the internal 4-byte header structure used in PostgreSQL varlena format. Attempting to insert, aggregate, or update a JSONB value beyond this threshold triggers an immediate engine exception: `ERROR: total size of jsonb array elements exceeds the maximum of 268435455 bytes` (SQLSTATE 54000).

Understanding why this boundary exists requires examining the internal storage structures of PostgreSQL. In relational database design, developers often treat JSONB as an unbounded document store. However, PostgreSQL manages JSONB not as arbitrary text, but as a parsed, decomposed binary tree engineered for rapid key extraction, containment queries, and indexing. That performance optimization introduces strict structural ceilings that do not apply to raw strings.

### How the 28-Bit JEntry Header Caps JSONB

Inside the PostgreSQL source code (specifically in `src/include/utils/jsonb.h` and `src/backend/utils/adt/jsonb_util.c`), every JSONB container is stored as a variable-length attribute (`varlena`). A JSONB container consists of a 4-byte header describing the container type (array or object) and element count, followed by an array of 4-byte headers called `JEntry` structures for each element, and finally the raw binary data.

Each 32-bit `JEntry` word encodes two distinct pieces of information:
* **Type Tags (4 bits):** Flags indicating whether the item is a string, number, boolean true, boolean false, null, or a nested container.
* **Offset or Length (28 bits):** The byte offset or length of the item data within the container buffer.

Because the offset and length fields are masked by `JENTRY_OFFLENMASK` (`0x0FFFFFFF`), the maximum addressable offset within any single JSONB container is exactly `2^28 - 1`, which equals `268,435,455 bytes`. The engine cannot address byte offsets beyond this boundary. If an incoming JSON string or document tree serializes to a binary payload exceeding `268,435,455 bytes`, PostgreSQL rejects the datum with a `PROGRAM_LIMIT_EXCEEDED` error code.

This `256MB` cap applies per value, meaning per table cell in a single row. It is not a limit on table size or the sum of all rows. However, because developers often store large arrays, nested event traces, or AI document corpora inside a single column, hitting this internal ceiling in production is a common failure mode.

### The Critical Distinction: JSONB Container vs. `1GB` TOAST Ceiling

A frequent point of confusion among database administrators and backend engineers is the difference between PostgreSQL's general field size limit and the JSONB container cap. Many technical articles claim that PostgreSQL supports up to `1GB` per JSON field. That claim is only half true.

PostgreSQL's underlying variable-length storage engine allows individual fields of types like `text`, `varchar`, and `bytea` to reach up to `1GB` (`2^30 - 1` bytes, or 1,073,741,823 bytes). In those types, the 4-byte varlena header dedicates 30 bits to length tracking and 2 bits to storage flags. The plain `json` data type (as opposed to `jsonb`) stores data as an unparsed, literal text string. Because plain `json` does not construct a `JEntry` binary structure, a plain `json` column can store documents up to `1GB`.

When you use `jsonb`, however, the binary parser decomposes the JSON structure upon write. The 28-bit `JEntry` offset mask lowers the ceiling from `1GB` down to `256MB`. Teams migrating from `json` or `text` to `jsonb` to take advantage of indexing frequently run into this hard barrier when handling payloads between `256MB` and `1GB`.

| Storage Layer or Data Type | Hard Ceiling | Internal Enforcement Point | Storage Representation | Operational Best Fit |
| --- | --- | --- | --- | --- |
| JSONB Column Value | `268,435,455 bytes` (~256 MB) | 28-bit `JEntry` offset mask (`JENTRY_OFFLENMASK`) | Parsed binary container with header metadata | Filterable semi-structured document attributes |
| Plain Text JSON (`json`) | 1 GB (1,073,741,823 bytes) | 30-bit `varlena` length word | Raw text string in TOAST storage | Append-only raw event logs without key indexing |
| Text or Bytea Column | 1 GB (1,073,741,823 bytes) | 30-bit `varlena` length word | Raw byte stream or text in TOAST storage | Unstructured document text, binaries, or archives |
| Table Row Heap Tuple | `8 KB` (minus page header) | Fixed 8192-byte page (`BLCKSZ`) boundary | Inline row slot before TOAST out-of-line storage | Normalized relational record state |
| Recommended Operational JSONB | Under `100 KB` | Engineering guideline for database throughput | Inline heap or single TOAST chunk | High-throughput OLTP, point lookups, filter predicates |

All technical specifications reflect PostgreSQL 14 through PostgreSQL 18 storage implementations.

## How TOAST Manages Large JSONB Documents on Disk and in Memory

PostgreSQL stores table data in fixed-size blocks called heap pages, which default to `8 KB` (`BLCKSZ = 8192` bytes). A single table row cannot span multiple pages. To accommodate attributes larger than an `8 KB` page, PostgreSQL relies on TOAST (The Oversized-Attribute Storage Technique). Understanding how TOAST handles JSONB columns reveals why large documents create silent performance bottlenecks long before reaching the `256MB` limit.

### The Mechanics of Out-of-Line Storage

When a row containing variable-length data exceeds `TOAST_TUPLE_THRESHOLD` (normally `2 KB`), the database storage engine evaluates the row for compression and out-of-line storage. The storage engine recognizes four storage strategies:

* **EXTENDED:** The default strategy for `jsonb`, `text`, and `bytea`. The system first attempts to compress the value. If the row remains wider than `TOAST_TUPLE_TARGET` (normally `2 KB`), it moves the data out-of-line into an auxiliary TOAST table.
* **EXTERNAL:** Moves wide values out-of-line into the TOAST table without attempting compression.
* **MAIN:** Compresses the value inline but avoids out-of-line storage unless no other option allows the row to fit inside an `8 KB` page.
* **PLAIN:** Prevents both compression and out-of-line storage. Only fixed-width or short data types support PLAIN.

When a JSONB document is moved out-of-line, PostgreSQL chunks the payload into segments of at most `TOAST_MAX_CHUNK_SIZE` (approximately 2000 bytes, allowing four chunks per `8 KB` page). These chunks are written as individual rows in the table's dedicated TOAST relation (`pg_toast_<table_oid>`). In the main table's heap page, the original column value is replaced by an 18-byte on-disk pointer containing the TOAST table OID, the chunk ID, the logical uncompressed size, and the physical stored size.

### The `256MB` Decompression Trap

Because TOAST compresses data using `pglz` or `lz4` before moving it out-of-line, a repetitive JSON document of `280MB` might compress down to `40MB` on disk. A developer might assume that because the stored data fits well within PostgreSQL disk blocks, the operation is safe.

This is where the decompression trap snaps shut. PostgreSQL enforces the `268,435,455-byte` limit on the **uncompressed logical representation** of the JSONB container, not on its compressed on-disk footprint. When an application executes an update or query that requires PostgreSQL to inspect or reconstitute the JSONB container, the engine must decompress the chunks into memory. If the uncompressed binary data exceeds `268,435,455 bytes`, the query fails instantly.

### Detoasting Latency and Memory Overhead

Even when JSONB values stay below `256MB` (for instance, documents between 5MB and `50MB`), TOAST storage introduces substantial overhead during query execution:

* **Full Retrieval Penalty:** When an application queries a specific key from a large JSONB column (such as `SELECT data->'metadata'->>'status' FROM records WHERE id = 42;`), PostgreSQL cannot seek directly to that offset within the TOAST table. The storage engine must fetch every out-of-line chunk from disk, reassemble the compressed byte stream, decompress the full payload in backend memory, and then traverse the binary tree to extract the single requested string.
* **Memory Churn in Backend Processes:** Decompressing and constructing large JSONB containers consumes significant RAM in backend PostgreSQL processes (`palloc`). A table scan over a few dozen rows containing `20MB` JSONB documents can allocate gigabytes of transient memory, evicting active database pages from the PostgreSQL buffer pool (`shared_buffers`) and the operating system page cache.
* **No Partial Detoasting for JSONB:** Unlike the `text` data type with `EXTERNAL` storage, where PostgreSQL can perform optimized substring reads on out-of-line chunks without reading the entire document, JSONB always requires complete container detoasting and parsing.

## GIN Indexing Pitfalls and Write Amplification on Deep JSONB Trees

The primary reason developers choose `jsonb` over plain `json` is indexing. PostgreSQL provides Generalized Inverted Index (GIN) support, enabling index-accelerated searches across arbitrary keys, containment expressions, and JSONPath queries. However, creating a GIN index over multi-megabyte JSONB documents is one of the most common causes of catastrophic database performance degradation.

### How GIN Indexes Explode on Large Documents

A standard B-Tree index maps a single column value to a tuple identifier (TID). In contrast, a GIN index is an inverted index: it extracts multiple component keys from each indexed datum and maps each individual key to a list of rows containing that key (a posting list or posting tree).

When you create a default GIN index on a JSONB column (`CREATE INDEX idx_data ON events USING GIN (payload);`), PostgreSQL uses the default `jsonb_ops` operator class. This operator class creates an index entry for:
1. Every single key in every object across the entire hierarchy.
2. Every single scalar value associated with every key.
3. Every element in every array.

If a table contains small documents of 1 KB, a document might yield 15 to 30 index entries. But if you insert a `10MB` or `50MB` JSONB tree representing an AI agent's execution history, complex AST metadata, or scraped web structures, that single document can contain hundreds of thousands of distinct paths, keys, and values.

Inserting that single row forces PostgreSQL to generate hundreds of thousands of index postings. The resulting GIN index quickly balloons to three to ten times the size of the original table heap, consuming tens of gigabytes of disk space and memory.

### Write Latency Spikes and gin_pending_list_limit

To prevent every write from performing expensive random writes across the GIN tree, PostgreSQL uses a fast-update buffer known as the pending list (`fastupdate = on`). Incoming index keys are appended to this pending list in sequential order.

When the pending list exceeds `gin_pending_list_limit` (which defaults to `4MB`), the inserting transaction is forced to pause and execute `gin_clean_pending_list`, sorting and merging the pending entries into the main GIN balanced tree.

On tables containing large JSONB documents, a single INSERT statement can generate more than `4MB` of index keys on its own. Consequently, every write operation breaches `gin_pending_list_limit`, forcing synchronous in-line merges on every transaction. What should be a 5-millisecond write turns into a multi-second stall, blocking application worker threads and causing connection pool exhaustion.

### MVCC and the Immutability Write Penalty

PostgreSQL uses Multi-Version Concurrency Control (MVCC) to provide transactional isolation. In PostgreSQL, updates are never performed in place on existing heap tuples. When an application updates a single field inside a JSONB column, PostgreSQL must:
* Write an entirely new version of the row tuple in the main table heap.
* Re-compress and duplicate the entire JSONB payload in the TOAST table.
* Mark the old row version and its TOAST chunks as dead.
* Insert an entirely new set of index entries into the GIN index for the new document version.

If your application updates a `20MB` JSONB document to change a single boolean flag from `false` to `true`, PostgreSQL writes `20MB` of new data to TOAST, writes corresponding write-ahead log (WAL) records, and generates thousands of new GIN index postings. The old `20MB` document remains on disk until `VACUUM` processes the dead tuple. Under moderate write traffic, this behavior causes massive WAL volume, replica replication lag, and severe disk bloat.

### Operator Classes: jsonb_ops vs. jsonb_path_ops vs. Expression Indexes

When JSONB indexing is required, choosing the correct index strategy dramatically reduces bloat and write overhead.

```sql
-- Default: jsonb_ops (Indexes keys and values separately)
-- Supports ?, ?|, ?&, @>, @?, @@ operators
CREATE INDEX idx_events_ops ON events USING GIN (payload);

-- Optimized: jsonb_path_ops (Hashes path + value together)
-- Supports @>, @?, @@ operators only; three to six times smaller index size
CREATE INDEX idx_events_path ON events USING GIN (payload jsonb_path_ops);

-- Best Practice: Targeted B-Tree Expression Index on hot fields
-- Extremely compact, zero full-document indexing overhead
CREATE INDEX idx_events_user_id ON events (((payload->>'user_id')::uuid));

```
The technical difference between a `jsonb_ops` and a `jsonb_path_ops` GIN index is that `jsonb_ops` creates independent index items for each key and value in the data, while `jsonb_path_ops` creates index items only for each value in the data, hashing the full key path leading to that value into a single 32-bit hash. A `jsonb_path_ops` index is typically three to six times smaller than a `jsonb_ops` index on the same data and executes containment queries (`@>`) faster.

However, for high-throughput production systems, the most reliable pattern is avoiding full-document GIN indexes entirely. Define B-Tree expression indexes on the specific extracted paths your application queries frequently.

## When to Offload Large Payloads from Relational Tables: Architectural Patterns

The hard `256MB` container cap, TOAST detoasting latency, and GIN index amplification highlight a clear operational rule: **keep individual PostgreSQL JSONB documents under `100 KB`.**

When JSON payloads exceed `100 KB`, they cease to function like relational attributes and start behaving like unstructured binary files. Engineering teams handling large payloads, complex configuration catalogs, or AI agent context can adopt three architectural alternatives to protect relational database performance.

### Pattern 1: Relational Normalization

The most direct solution for large JSONB arrays is relational normalization. If a JSONB document hits the `256MB` limit because it contains an array of hundreds of thousands of event objects, those objects belong in a separate relational table:

```sql
-- Anti-pattern: hundreds of thousands of events in one JSONB array
CREATE TABLE execution_runs (
    run_id uuid PRIMARY KEY,
    events jsonb -- Breaches `256MB` limit on long runs
);

-- Normalized: Relational one-to-many model
CREATE TABLE execution_runs (
    run_id uuid PRIMARY KEY,
    started_at timestamptz NOT NULL,
    status text NOT NULL
);

CREATE TABLE execution_events (
    event_id bigserial PRIMARY KEY,
    run_id uuid REFERENCES execution_runs(run_id) ON DELETE CASCADE,
    event_type text NOT NULL,
    payload jsonb -- Compact, < 5 KB per event
);
CREATE INDEX idx_exec_events_run_id ON execution_events (run_id);

```
Normalizing arrays into child rows eliminates the `256MB` ceiling, enables standard pagination and streaming with `LIMIT` and `OFFSET`, and allows index updates to affect only the specific modified row rather than a monolithic document.

### Pattern 2: Database Pointers with Object Storage

When documents cannot be cleanly normalized, such as raw JSON dumps from external APIs, full-page web scrapes, or compiled execution logs, store only metadata in PostgreSQL and write the payload to an external object store:

```sql
CREATE TABLE raw_ingestions (
    ingestion_id uuid PRIMARY KEY,
    source text NOT NULL,
    content_type text NOT NULL,
    byte_size bigint NOT NULL,
    checksum text NOT NULL,
    storage_uri text NOT NULL, -- s3://bucket/path or workspace path
    created_at timestamptz DEFAULT now()
);

```
PostgreSQL handles transactional queries, foreign keys, and access controls, while the file storage layer handles multi-megabyte payloads without TOAST overhead or buffer pool starvation.

### Pattern 3: Offloading to Intelligent Workspaces for Agentic Workflows

For autonomous AI agents and engineering teams building with LLMs, the problem is intensified. Agents produce and consume multi-megabyte context corpora: complete tool execution traces, documentation repositories, customer interaction archives, and prompt template libraries.

Attempting to store these corpora inside PostgreSQL JSONB columns leads straight to the `256MB` cap, GIN index stalls, and high database maintenance costs. Moving them to commodity object storage (like AWS S3 or Google Cloud Storage) solves the raw byte problem but creates a retrieval gap: the files remain inert, requiring custom vector databases, chunking pipelines, and synchronization scripts to make them searchable.

A more effective pattern is placing the agent corpus into an intelligent workspace platform like Fast.io:

* **Automatic Hybrid Indexing via Intelligence Mode:** In Fast.io, files stored in an org-owned workspace are automatically indexed for hybrid search, combining full-text keyword matching with semantic vector retrieval. An agent searching a `100MB` collection of API specifications or technical manuals does not need the entire file loaded into its context window or stored in a database column. The agent queries the workspace and retrieves only the precise excerpts needed for its turn.
* **Structured Extraction with Metadata Views:** For teams that need structured relational querying across semi-structured files, Fast.io's [Metadata Views](/product/document-data-extraction/) turn documents into live, queryable tables. Users describe fields in plain language, and the system populates typed schemas (Text, Integer, Decimal, Boolean, URL, JSON, Date & Time) across PDFs, spreadsheets, and Word documents without OCR templates or manual parsing rules.
* **Direct MCP Integration for AI Workflows:** Fast.io provides remote Model Context Protocol (MCP) server endpoints running over Streamable HTTP. Coding agents connect via `https://mcp.fast.io/mcp/code`, while Claude and general agents connect via `https://mcp.fast.io/mcp/tools` (refer to the [setup documentation](https://mcp.fast.io/docs) for configuration instructions). Agents read, write, and search persistent workspace files directly through standard tool calls.
* **Per-File Version History and Audit Logs:** Every file update retains full version history, protecting against concurrent overwrite conflicts when multiple agents collaborate on a shared project. The append-only audit log records every action for full operational visibility.

Monthly plans start with a 14-day free trial, which requires a credit card. Subscription tiers scale across Starter (`$9.99/mo` for 3 seats, `250 GB` storage, 5 workspaces, and `100,000` credits), Business (`$49.99/mo` for 10 seats, `5 TB` storage, 50 workspaces, and `600,000` credits), and Enterprise (`$199.99/mo` for 30 seats included, `25 TB` storage, 200 workspaces, and `3,000,000` credits) on the [pricing page](/pricing/). Credits meter AI operations; overage is `$10` per `100,000` credits. Additional storage is billed at 1.5 cents per GB a month and extra bandwidth at 4 cents per GB.

## How to Audit and Optimize PostgreSQL JSONB Tables in Production

If your application currently stores large JSONB documents in PostgreSQL, running an audit of your storage footprint and query performance will identify bloat and prevent out-of-memory errors before hitting the `256MB` cap.

### 1. Identify Bloated JSONB Rows

Use PostgreSQL's built-in `pg_column_size()` function to evaluate the physical stored byte size of your JSONB column across the table:

```sql
SELECT
    count(*) AS total_rows,
    pg_size_pretty(avg(pg_column_size(payload))::bigint) AS avg_size,
    pg_size_pretty(max(pg_column_size(payload))) AS max_size,
    count(*) FILTER (WHERE pg_column_size(payload) > 1048576) AS rows_over_1mb,
    count(*) FILTER (WHERE pg_column_size(payload) > 10485760) AS rows_over_10mb,
    count(*) FILTER (WHERE pg_column_size(payload) > 104857600) AS rows_over_100mb
FROM app_data;

```
If `max_size` approaches `200MB`, or if thousands of rows exceed `1MB`, your table is experiencing heavy TOAST reliance and is at risk of breaching the `256MB` container cap during uncompressed serialization.

### 2. Measure Table, TOAST, and Index Disk Footprint

Inspect how much physical storage is consumed by the table heap, its auxiliary TOAST table, and associated indexes:

```sql
SELECT
    c.relname AS table_name,
    pg_size_pretty(pg_relation_size(c.oid)) AS heap_size,
    pg_size_pretty(pg_relation_size(c.reltoastrelid)) AS toast_size,
    pg_size_pretty(pg_total_relation_size(c.reltoastrelid)) AS total_toast_with_index,
    pg_size_pretty(pg_indexes_size(c.oid)) AS index_size,
    pg_size_pretty(pg_total_relation_size(c.oid)) AS grand_total
FROM pg_class c
WHERE c.relname = 'app_data';

```
In tables with bloated JSONB columns, `toast_size` and `index_size` frequently account for the vast majority of `grand_total`.

### 3. Switch TOAST Compression to LZ4 (PostgreSQL 14+)

Starting with PostgreSQL 14, administrators can configure LZ4 compression for TOAST-able columns. LZ4 provides substantially faster compression and decompression speeds compared to PostgreSQL's default `pglz` algorithm, substantially reducing CPU detoasting overhead during query execution:

```sql
-- Alter existing column to use LZ4 compression
ALTER TABLE app_data ALTER COLUMN payload SET COMPRESSION lz4;

-- Existing rows remain compressed with pglz until updated.
-- To rewrite existing data using LZ4:
VACUUM FULL app_data;

```
### 4. Replace Full-Document GIN Indexes with Targeted Expressions

If your table has an unconstrained GIN index on a large JSONB column, drop it and replace it with targeted B-Tree indexes on the specific fields your application queries:

```sql
-- Drop the bloated full-document GIN index
DROP INDEX CONCURRENTLY IF EXISTS idx_app_data_payload_gin;

-- Add targeted B-Tree indexes for specific lookup fields
CREATE INDEX CONCURRENTLY idx_app_data_customer_id
    ON app_data (((payload->>'customer_id')::uuid));

CREATE INDEX CONCURRENTLY idx_app_data_status
    ON app_data (((payload->>'status')::text))
    WHERE (payload->>'status') IS NOT NULL;

```
Targeted B-Tree expression indexes consume a tiny fraction of the disk space of a full GIN index, update in microseconds during writes, and completely avoid the `gin_pending_list_limit` write stalls.

## Frequently asked questions

### What is the maximum size of a JSONB column in PostgreSQL?

The maximum size of a single JSONB value in PostgreSQL is 268,435,455 bytes (approximately `256MB`). This limit is enforced by the internal 28-bit length and offset mask (JENTRY_OFFLENMASK) within PostgreSQL's binary JSONB container header.

### Can PostgreSQL JSONB exceed `256MB`?

No, an individual JSONB value cannot exceed `268,435,455 bytes` decompressed. Attempting to store or aggregate a JSONB document beyond this boundary raises a PROGRAM_LIMIT_EXCEEDED error. For larger payloads up to `1GB`, you must use plain text JSON, text, bytea, or external file storage.

### How does PostgreSQL TOAST handle large JSONB documents?

When a table row exceeds `2 KB`, PostgreSQL's TOAST storage engine compresses the JSONB value and moves it out-of-line into an auxiliary TOAST table, splitting the payload into chunks of roughly 2000 bytes. The main table row retains only an 18-byte pointer to the out-of-line data.

### Why does PostgreSQL allow `1GB` for text columns but only `256MB` for JSONB?

PostgreSQL variable-length storage (varlena) supports up to `1GB` by allocating 30 bits of its 4-byte header to length tracking. While text and plain JSON store raw characters using that 30-bit word, JSONB parses data into a binary tree whose JEntry headers allocate only 28 bits to offsets and lengths.

### What error occurs when a JSONB document exceeds `256MB` in PostgreSQL?

When a JSONB document exceeds `268,435,455 bytes`, PostgreSQL rejects the query with the error message: 'ERROR: total size of jsonb array elements exceeds the maximum of `268,435,455 bytes`' or 'ERROR: string too long to represent as jsonb string' with SQLSTATE 54000.

### How does GIN indexing affect write performance on large JSONB columns?

Default GIN indexes (jsonb_ops) extract every key and value from a JSONB document into individual index items. On multi-megabyte documents, a single write generates hundreds of thousands of postings, rapidly blowing past the `4MB` gin_pending_list_limit and causing multi-second write stalls.

### What is the difference between jsonb_ops and jsonb_path_ops for large documents?

The jsonb_ops operator class indexes each key and value independently, supporting key existence and containment operators. The jsonb_path_ops operator class hashes the full key path and value together into a 32-bit hash, producing an index that is three to six times smaller and much faster for containment queries.

### What is the recommended maximum operational size for a JSONB column?

Database engineering best practices recommend keeping individual JSONB documents below `100 KB` in PostgreSQL. Documents exceeding `100 KB` incur heavy TOAST decompression penalties, increase memory churn in backend worker processes, and cause severe write amplification during updates.

## Sources

- [PostgreSQL Documentation: TOAST](https://www.postgresql.org/docs/current/storage-toast.html): PostgreSQL TOAST limits the logical size of any value of a TOAST-able data type to 1 GB.
- [PostgreSQL Documentation: JSON Types](https://www.postgresql.org/docs/current/datatype-json.html): A jsonb_ops GIN index creates independent index items for each key and value in the data, while jsonb_path_ops creates items only for each value.

## About Fast.io

Fast.io provides shared workspaces where people and AI agents work on the same files, with built-in semantic search and citation-backed chat over what they hold. Agents reach it through a remote MCP server, a REST API at https://api.fast.io/current/, and a command line client published on npm as @vividengine/fastio-cli. MCP setup is at https://mcp.fast.io/docs: Claude and most MCP clients connect to https://mcp.fast.io/mcp/tools, ChatGPT to https://mcp.fast.io/mcp/operations, and coding agents to https://mcp.fast.io/mcp/code.
