Limits set in the code are in src/domain.ts unless another file is named. Sizes are binary: 1 MiB is 1,048,576 bytes.
Documents
| Limit | Value |
|---|---|
| Upload file types | PDF, PNG, JPEG, WebP. The type is detected from the file’s first bytes and must match the type the browser sends. |
| PDF size | 10 MiB |
| PDF pages | 25 |
| PDF text | A text layer is needed. Scanned PDFs without text are flagged pdf_no_text. There is no built-in OCR or PDF rasterisation. |
| Image size | 4 MiB |
| Images per read | 1 |
| Files per upload | 10 (src/invoices.ts) |
| Files per share from another app | 10, PDF, PNG, JPEG or WebP. Others are left out. (src/pwa.ts) |
| Upload request body | 40 MiB in total |
| Text read per document | 40,000 characters of document text plus email context. Longer input is cut and flagged input_truncated. |
| Read lease | 120 seconds. A read that has not finished by then can be taken over by another. |
| Currencies | EUR, USD, GBP, CHF, SEK, NOK, DKK, CAD, AUD, JPY |
| Money tolerance | 2 minor units for net + VAT = total, and for matching amounts |
| Limit | Value |
|---|---|
| Email size | 20 MiB. Larger mail is dropped. |
| Attachments read per email | 10 supported attachments (PDF, PNG, JPEG, WebP). More are skipped and flagged email_skipped_parts. |
| Allowed senders | 75 addresses of up to 254 characters. The longest list fits the 20,000-character limit on a stored setting. |
| Emails from new senders waiting | 50 in total and 10 from one sender. More are logged, not kept. |
| Ignored senders | 500 addresses |
| Mail log | The last 500 emails, plus every email from a new sender still waiting. |
| Forward copy | 1 address |
| Seller names | 20 names of up to 100 characters |
Bank statement import
| Limit | Value |
|---|---|
| File size | 2 MiB, for XLSX, CSV and PDF statements |
| PDF statement pages | 400 (src/pdf.ts) |
| Rows per file | 1 to 5,000 |
| Columns | 100 |
| Rows above the column names, or skipped at the end | 100 each |
| Cell size | 64 KiB |
| Saved mapping | 32 KiB |
| Preview validity | 30 minutes |
Month package and OneDrive
| Limit | Value |
|---|---|
| Files per month package | 900 (src/package.ts) |
| Packages with a known size and progress | Up to 400 files |
| OneDrive files per request | 10 (src/onedrive.ts) |
| OneDrive single upload | Up to 4 MiB per file; larger files use an upload session |
| OneDrive sign-in window | 10 minutes between Connect and the return from Microsoft |
Configuration
| Limit | Value |
|---|---|
| Products | 1 to 200; ids and labels 1 to 100 characters. Saved in the app, the whole list must also fit the 20,000-character limit on a stored setting; the app refuses a longer one with an error. |
APP_NAME |
60 characters |
EXPORT_PREFIX |
40 characters |
ACCOUNTANT_LABEL |
100 characters |
SEND_HINT |
300 characters |
SOURCE_REPOSITORY |
300 characters |
APP_BASE_PATH |
60 characters |
| Stored app setting | 20,000 characters of JSON per value (schema/0004_settings.sql) |
Use
| Limit | Value |
|---|---|
| Users | One user per deployment, with one shared password, or the emails in ACCESS_ALLOWED_EMAILS in Access mode. No roles. |
| Sign-out | None with HTTP Basic. Access mode has Sign out. |
| Bank connections | XLSX, CSV and PDF statement import only. No bank API sync, no scanned PDF statements. |
| Bulk actions | 500 rows per action (BULK_CAP in src/bulk.ts). On a list with more, the button reads Select the first 500, in the list’s order. Match on Bank takes up to 100 matches at a time (src/match.ts). Read again and Move send 10 per request, and the page sends them in groups with a progress bar (src/bulk.ts). |
| Matching | One bank row per document. Split and combined payments, refunds, fees and currency conversion are not matched automatically. |
Cloudflare plan limits
These are Cloudflare’s limits, not the app’s. Check the linked pages for current values.
| Limit | Workers Free | Workers Paid | Where it matters |
|---|---|---|---|
| CPU time per request | 10 ms | 30 s by default, up to 5 min | Reading a PDF, building a large month package, importing a large CSV. Exceeding it shows Error 1102. |
| Subrequests to Cloudflare services per request | 1,000 | 10,000 by default | Each file in a month package is one R2 read. |
| External subrequests per request | 50 | 10,000 by default | Frankfurter and Microsoft Graph calls. |
| Workers AI | 10,000 Neurons a day, then calls fail until 00:00 UTC | Billed per use | Clairic and Clef. |
R2 needs an R2 subscription and a payment method on the account, even when usage stays inside the free allowance. Without it the originals bucket cannot be created.
Sources: Workers limits, Workers pricing, Workers AI pricing, D1 limits, R2 pricing.