Summary
pdfToMarkdown and friends are synchronous and run to completion in one go. On Cloudflare Workers
that is awkward: CPU time is metered per invocation (10 ms on the free plan, 30 s default on paid,
5 min maximum), and a synchronous parse holds the isolate for its entire duration with no opportunity
to yield, checkpoint, or report progress.
Measurement
Parse time scales roughly linearly with content (Node 25.9.0, process.hrtime.bigint(), so
indicative of magnitude rather than exact workerd figures):
paras= 60 pdf=0.02 MiB parse= 101 ms
paras= 600 pdf=0.13 MiB parse= 568 ms
paras=3000 pdf=0.62 MiB parse= 2623 ms
Extrapolating, a 5 MB PDF lands near 20 s — inside the paid 30 s default but not comfortably — and a
25 MB one would exceed even the 5-minute maximum. On the free plan's 10 ms, even the smallest test
document is 10× over budget.
For contrast, the reason this matters specifically on Workers: a remote conversion service reached
over a binding is network I/O, which does not count toward CPU time at all. Moving that work
in-process converts a free operation into the metered one. That is a fair trade for losing a remote
dependency, but it needs an API that makes the cost manageable.
Ask
Some way to parse incrementally, so a caller can budget CPU. Rough options, no strong preference:
- An async page-at-a-time API —
AsyncIterable<PageContent>, or a callback invoked per page,
yielding to the event loop between pages. Lets a caller stop at a deadline and resume, or stream
results.
- An
AbortSignal checked mid-parse. The conversion functions already accept signal; if it is
only checked at hop boundaries rather than during the page loop, a long single-document parse
cannot actually be cancelled. Honouring it inside the loop would at least make a deadline
enforceable.
- A documented cost model — even just "parse is O(content length), expect roughly N ms/MB" in the
README would let consumers decide statically whether to do this inline or hand it to a queue.
(2) may already be true — I did not verify how granularly signal is checked, so treat that as a
question rather than a claim.
Note
Much of the actual parsing lives in pdf-codec, so a real incremental API probably needs changes
there too; filing here because this is the public surface consumers hold, and the shape of the
answer should be decided at this level.
Summary
pdfToMarkdownand friends are synchronous and run to completion in one go. On Cloudflare Workersthat is awkward: CPU time is metered per invocation (10 ms on the free plan, 30 s default on paid,
5 min maximum), and a synchronous parse holds the isolate for its entire duration with no opportunity
to yield, checkpoint, or report progress.
Measurement
Parse time scales roughly linearly with content (Node 25.9.0,
process.hrtime.bigint(), soindicative of magnitude rather than exact workerd figures):
Extrapolating, a 5 MB PDF lands near 20 s — inside the paid 30 s default but not comfortably — and a
25 MB one would exceed even the 5-minute maximum. On the free plan's 10 ms, even the smallest test
document is 10× over budget.
For contrast, the reason this matters specifically on Workers: a remote conversion service reached
over a binding is network I/O, which does not count toward CPU time at all. Moving that work
in-process converts a free operation into the metered one. That is a fair trade for losing a remote
dependency, but it needs an API that makes the cost manageable.
Ask
Some way to parse incrementally, so a caller can budget CPU. Rough options, no strong preference:
AsyncIterable<PageContent>, or a callback invoked per page,yielding to the event loop between pages. Lets a caller stop at a deadline and resume, or stream
results.
AbortSignalchecked mid-parse. The conversion functions already acceptsignal; if it isonly checked at hop boundaries rather than during the page loop, a long single-document parse
cannot actually be cancelled. Honouring it inside the loop would at least make a deadline
enforceable.
README would let consumers decide statically whether to do this inline or hand it to a queue.
(2) may already be true — I did not verify how granularly
signalis checked, so treat that as aquestion rather than a claim.
Note
Much of the actual parsing lives in
pdf-codec, so a real incremental API probably needs changesthere too; filing here because this is the public surface consumers hold, and the shape of the
answer should be decided at this level.