PAGI
view release on metacpan or search on metacpan
lib/PAGI/Server.pm view on Meta::CPAN
=item max_body_size => $bytes
Maximum request body size in bytes. Default: 10,000,000 (10MB).
Set to 0 for unlimited (not recommended for public-facing servers).
Requests with Content-Length exceeding this limit receive HTTP 413
(Payload Too Large). Chunked requests are also checked as data arrives.
B<Example:>
my $server = PAGI::Server->new(
app => $app,
max_body_size => 50_000_000, # 50MB for file uploads
);
# Unlimited (use with caution)
my $server = PAGI::Server->new(
app => $app,
max_body_size => 0,
);
B<CLI:> C<--max-body-size 50000000>
B<Security note:> Without a body size limit, attackers can exhaust server
memory with large requests. The 10MB default balances security with common
use cases (file uploads, JSON payloads). Increase for specific needs, or
use 0 only behind a reverse proxy that enforces its own limit.
=over 4
=item * A listening socket is created before forking
=item * Worker processes are spawned using C<< $loop->fork() >> which properly
handles IO::Async's C<$ONE_TRUE_LOOP> singleton
=item * Each worker gets a fresh event loop and runs lifespan startup independently
=item * Workers that exit are automatically respawned via C<< $loop->watch_process() >>
=item * SIGTERM/SIGINT triggers graceful shutdown of all workers
=back
=item sync_file_threshold => $bytes
Threshold in bytes for synchronous file reads. Files smaller than this value
are read synchronously in the event loop; larger files use async I/O via
a worker pool.
B<Default:> 65536 (64KB)
Set to 0 for fully async file reads. This is recommended for:
=over 4
=item * Network filesystems (NFS, SMB, cloud storage)
=item * High-latency storage (spinning disks under load)
=item * Docker volumes with overlay filesystem
=back
The default (64KB) is optimized for local SSDs where small synchronous reads
are faster than the overhead of async I/O.
B<CLI:> C<--sync-file-threshold NUM>
=item max_requests => $count
Maximum number of requests a worker process will handle before restarting.
After serving this many requests, the worker gracefully shuts down and the
parent spawns a replacement.
B<Default:> 0 (disabled - workers run indefinitely)
B<When to use:>
=over 4
=item * Long-running deployments where gradual memory growth is a concern
=item * Applications with known memory leaks that can't be easily fixed
=item * Defense against slow memory growth (~6.5 bytes/request observed in PAGI)
=back
B<Note:> Only applies in multi-worker mode (C<< workers > 0 >>). In single-worker
mode, this setting is ignored.
B<CLI:> C<--max-requests 10000>
Example: With 4 workers and max_requests=10000, total capacity before any
restart is 40,000 requests. Workers restart individually without downtime.
=item timeout => $seconds
Connection idle timeout in seconds. Closes connections that are idle between
requests (applies to keep-alive connections waiting for the next request).
B<Default:> 60
B<Performance note:> Each connection with a non-zero timeout creates a timer
that is reset on every read event. For maximum throughput in high-performance
scenarios, set C<timeout =E<gt> 0> to disable the idle timer entirely. This
eliminates timer management overhead but means idle connections will never
be automatically closed.
B<Example:>
# Disable idle timeout for maximum performance
my $server = PAGI::Server->new(
app => $app,
timeout => 0,
);
# Short timeout to reclaim connections quickly
my $server = PAGI::Server->new(
app => $app,
( run in 1.912 second using v1.01-cache-2.11-cpan-39bf76dae61 )