Limits
Every fixed limit in Lific that a person, script or agent can run into, what it applies to, and what happens when it is exceeded.
Lific bounds anything a caller controls: request sizes, page sizes, how fast one address can try passwords, how much an archive may expand to. The numbers are built into the binary and cannot be changed in lific.toml. This page lists them so that a refusal is never a surprise.
Some limits refuse the request with an error that names the limit. Others quietly clamp the value you asked for, which is noted where it happens. A 429 or 503 from Lific carries a Retry-After header unless the table says otherwise.
Request size
| Limit | Value | Applies to | When exceeded |
|---|---|---|---|
| Request body | 2 MiB | Every REST request, unless listed below | 413 |
| Attachment upload request | 64 MiB | POST /api/attachments (the file itself is limited to 10 MiB, see Attachments) | 413 |
| Project archive upload request | 129 MiB | POST /api/project-archives | 413 |
| GitHub import request | 16 KiB | POST /api/projects/{id}/import/github | 413 |
| OAuth request body | 64 KiB | /oauth/* routes | 413 |
The 2 MiB ceiling also decides the largest issue description or page you can save over REST, since the text travels in the request body.
Content
| Limit | Value | Applies to | When exceeded |
|---|---|---|---|
| Comment body | 256 KiB | Creating a comment, everywhere | 400 (MCP: Error: text). A comment already larger than this from before the limit existed can be edited, but not made longer. |
| Mentions in one comment | 256 distinct @usernames | Comments | Refused with 400. Lific does not notify the first 256 and drop the rest. |
| Attachment references in one body | 256 distinct attachments | Issue descriptions, pages and comments | Refused with 400, because linking only some of them would unlink attachments the text still uses. |
| Project identifier | 1 to 5 characters: uppercase letters or digits, starting with a letter. DOC is reserved. | Creating a project | 400 |
| Password | 8 to 1,024 bytes | Signup, lific user create, password changes | 400 |
| Instance name | 60 characters | Instance settings | 400 |
| Login message | 280 characters | Instance settings | 400 |
| Session lifetime | 1 to 365 days (default 30) | Instance settings | 400 |
| Attachment alt text | 1,000 characters | Editing an attachment | 400 |
| Saved view configuration | 8 KiB | Saved views | 400 |
| Wait note | 500 characters | Waits on a person or a date, over REST and MCP link_issues | 400 (MCP: Error: text) |
| Issues created in one call | 50 | MCP create_issue with issues | Error: text, and nothing is created |
Pages of results
These never cause an error. A larger value is lowered to the cap, and a zero or negative limit becomes 1. When more results exist, the response says so and gives the offset for the next page.
| Where | Default | Cap |
|---|---|---|
| REST issue, plan and page lists | 50 (page lists return everything when you pass neither limit nor offset) | 500 |
| REST and CLI comment lists | 50 | 500 |
| REST and MCP activity feeds | 50 over REST, 30 for get_activity | 200 |
Search (REST, MCP and lific search) | 20 | 500 |
| Search offset | none | 100,000 |
MCP list_issues | 50 | 500 |
MCP list_resources | 100 for issues and pages, 50 for plans | 500 |
MCP list_comments | 50 | 500 |
MCP get_issue comments | the 3 most recent (include_comments=recent) | 500 most recent (all) |
MCP get_attachment text | 200 lines | 500 lines |
MCP export of a project | 20 documents | 100 documents, and at most 256 KiB of Markdown per response (always at least one document) |
lific issue list | 50 | 500 |
Project insights weeks | 12 | 52 |
A page of comments is also limited to about 2 MiB of response, counted after JSON encoding. A thread of long comments therefore returns fewer rows than you asked for, with a pointer to the next page. A short page does not mean the thread has ended.
Two MCP tools work on a fixed batch rather than pages. get_board shows at most 500 issues and says when older ones are left out. bulk_update changes at most 500 matching issues in one call.
MCP response budgets
Agent harnesses cut long tool output off without telling the agent, near 50 KB in some clients. These MCP tools hold their responses under fixed budgets instead, and say what they left out and which call returns it. None of them is an error.
| Tool | Limit | What happens |
|---|---|---|
get_page | 30,000 characters of page content per response | A longer page returns its outline (at most 10,000 characters of it) and its opening. A cut read ends with the call that continues it. Cuts move back to a line end within the last 2,000 characters. |
get_page with since_seq | 30,000 characters of diff | The diff is cut, with a note to read the changed sections instead. |
| Page writes over MCP | 30,000 characters | The write succeeds and the response notes that readers will get an outline. |
get_briefing | 6,000 characters in total | Lines are dropped from the longest sections until the response fits. |
get_briefing sections | 8 issues per issue section, 5 plans, 5 changes of each kind, titles cut at 80 characters | Each cut section says how many it left out and names the call that lists them. Issue and plan counts stop at 100 (100+). |
get_briefing pages | 10 pages | Further page identifiers are not reported; the section says how many were left out. |
create_issue duplicate hint | 3 similar open issues per new issue | Only the closest are listed. |
Page version history
Lific keeps recent versions of each page's content so get_page(since_seq=...) can return a diff. It keeps the newest 50 versions of each page and drops the oldest once they total more than 2,000,000 characters; the newest version is always kept. A seq older than the kept history gets the whole page instead of a diff. Versions are deleted with the page and are not part of project archives.
Search
| Limit | Value | When exceeded |
|---|---|---|
| Query length, normal mode | 4 KiB | 400 |
Query length, literal mode | 256 bytes | 400 |
Records matched in literal mode | 10,000 | 400, asking you to narrow the query |
| Attachment text indexed for search | Text files up to 512 KiB | Larger files are found by filename only |
Attachments
| Limit | Value | Applies to | When exceeded |
|---|---|---|---|
| File size | 10 MiB | Uploads over REST, the web UI and the MCP upload_attachment tool | 400 (MCP: Error: text) |
| Upload rate | 30 uploads per 10 minutes per user | REST uploads, including the web UI | 403 |
| Thumbnail source | 50 megapixels | Thumbnail generation | The upload succeeds without a thumbnail |
| ZIP preview | First 200 entries | Attachment previews | The listing is marked truncated |
Uploads are also checked against an allowlist of file types, read from the file's contents rather than its name. The MCP tool reference lists the types.
Sign-in and rate limits
Rate limits count requests per client address, and some also per account. Behind a reverse proxy, set trusted_proxies so Lific sees each visitor's address instead of the proxy's.
| Limit | Value | Counted per | When exceeded |
|---|---|---|---|
| Failed sign-ins | 5 per 15 minutes | Client address, and separately per username or email | 400 with the number of seconds to wait. Successful sign-ins do not count. |
| Re-entering your password before a sensitive action | 5 per 15 minutes | Client address, and separately per account | 400 with the wait. Successful confirmations do not count. |
| Password changes | 5 per 15 minutes | Client address, and separately per account | 400 with the wait. Successful changes do not count. |
| Signups | 5 per 15 minutes | Client address, and separately per email | 400 with the wait. Every attempt counts. |
| OAuth client registrations | 10 per hour | Client address | 429 |
OAuth device authorizations (lific login) | 10 per hour | Client address | 429 |
| Repository binding changes | 30 per hour | User | 400 with the wait |
| Public project reads | 240 per minute | Client address | 429 |
A request from a trusted proxy that carries an invalid X-Lific-Client-IP and X-Lific-Proxy-Secret pair gets 503 on these routes. See Configuration.
Concurrency
These limit how many expensive operations run at once on the whole instance. A request over the limit is refused immediately rather than queued.
| Limit | Value | When exceeded |
|---|---|---|
| Markdown exports in progress over REST and MCP | 2 | 429 (MCP: Error: text) |
| Browser project archive exports and imports in progress | 1 | 429 |
| GitHub imports from the web UI | 1 per project, 4 per instance | 409 |
| Public project requests in progress | 4 | 503 |
| Public attachment downloads in progress | 4 | 503 |
| Public thumbnail and preview generation | 1 at a time, from files up to 32 MiB | 503 when busy. A larger file gets 404 for a thumbnail that has not been made yet, and for a preview. |
| Realtime connections | 16 per user, 1,024 per instance | 429, without Retry-After |
A realtime connection is also closed if its client sends messages over 16 KiB, or more than 64 messages in 10 seconds. The web UI never does either.
Exports
These apply to Markdown exports from the web UI, REST, the MCP export tool and lific export. Each is checked before or while the export is built, and an export that would exceed one is refused with 400 rather than written partially.
| Limit | Value |
|---|---|
| Files in one export | 10,000 |
| Comments on one issue | 1,000 |
| Comments in one project export | 100,000 |
| One exported file | 8 MiB |
| Whole export, uncompressed | 128 MiB |
| Metadata entries in one export | 50,000 |
| Download stalls | The download ends after 30 seconds without progress, or after 30 minutes in total |
When lific export project runs with --backend http, it unpacks the server's ZIP with its own limits: 10,000 entries and 512 MiB once expanded.
Exporting several issues at once from the web UI stops at 16 MiB and shows an error instead of saving a partial file.
Project archives
A project archive made or read by the CLI works with the local database, so it gets larger limits than one uploaded or downloaded through the browser. An archive over a limit is refused with 413 in the browser and an error naming the limit in the CLI.
| Limit | CLI | Browser |
|---|---|---|
| Archive file (compressed) | 2 GiB | 128 MiB |
| Archive contents once expanded | 2 GiB plus 80 MiB | 256 MiB |
| Project data (the manifest) | 64 MiB | 16 MiB |
| One attachment | 256 MiB | 64 MiB |
| All attachments together | 2 GiB | 192 MiB |
| Distinct attachments | 10,000 | 2,000 |
| Rows across all tables | 200,000 | 50,000 |
A browser upload must finish within 120 seconds and may not stall for more than 20.
Restoring backups
lific restore checks an archive's expanded size before it writes anything, so an archive from someone else cannot fill the disk. An archive over a limit is refused. --allow-large raises the limits for an archive you made yourself; every other check still runs.
| Limit | Default | With --allow-large |
|---|---|---|
| Database file | 512 MiB | 16 TiB |
| One attachment | 64 MiB | 16 TiB |
| Everything together | 1 GiB | 16 TiB |
| Entries in the archive | 10,000 | 10 million |
| Manifest | 1 MiB | 64 MiB |
lific dump and the automatic backups have no size limit.
Imports and git hooks
| Limit | Value | When exceeded |
|---|---|---|
| GitHub issues in one import | 10,000 | 413 from the web UI, an error from the CLI |
| Comments on one GitHub issue | 1,000 | 413 / error |
| One response from GitHub | 8 MiB | 413 / error |
| Imported text in total | 128 MiB | 413 / error |
Commit messages in one git-hook request | 500 | 400 |
Issue references in one git-hook request | 500 | 400 |
Without a token, GitHub itself allows 60 requests an hour, which a large repository can use up.
OAuth
| Limit | Value | When exceeded |
|---|---|---|
| Access token lifetime | 30 days | The client must sign in again. Lific issues no refresh tokens. |
Device code lifetime (lific login) | 15 minutes | The code expires and the login has to start over |
| Device code polling | Every 5 seconds at most | Polling faster is answered with slow_down |
| Client name | 128 bytes, no control characters | 400 |
| Redirect URIs per client | 8, each up to 2,048 bytes | 400 |
| Registered clients | 1,024 per instance, 4 MiB in total | 429 until old ones are removed |
| Pending device codes | 1,024 per instance | 429 |
A registered client that has never been used is removed after 7 days, which frees room for new registrations.
Multiple instances
lific mcp --instances has its own limits on its configuration file, the number of instances, response sizes and timeouts. Multiple instances lists them.
The CLI's HTTP backend gives up on a request after 30 seconds.