Skip to main content

The Problem with Traditional PHP

Traditional PHP follows a “shared-nothing” architecture:
Every request:
  • Starts a new PHP process
  • Loads the framework from disk
  • Parses and compiles PHP files
  • Initializes dependencies
  • Finally executes your code
  • Destroys everything
Traditional PHP spends 50-80% of request time on startup overhead, not your actual code.

The Always-Alive Solution

Lyger’s Always-Alive architecture keeps PHP running in memory:
With Always-Alive, only your application code executes per request. The framework overhead is paid once at startup.

How It Works

Server Startup

Behind the Scenes

ServerManager

The ServerManager class orchestrates the persistent PHP worker:

Framework Preloading

PHP’s class autoloader caches parsed classes. Once loaded, subsequent instantiations are nearly instant.

Request Handling

When a request arrives:
  1. Rust receives HTTP request (port 8000)
  2. Rust parses request (method, URI, headers, body)
  3. Rust calls PHP via FFI with request data
  4. PHP executes router (already in memory)
  5. PHP returns response to Rust
  6. Rust sends HTTP response to client

Performance Benefits

Startup Time Comparison

Your actual application code execution time remains the same. The improvement comes from eliminating startup overhead.

Real-World Impact

Memory Considerations

Memory Usage

Always-Alive uses less total memory because the framework is loaded once, not per request. However, memory leaks are permanent until server restart.

Memory Leaks

In traditional PHP, memory leaks are cleared after each request. With Always-Alive, you must be careful:
  1. Avoid static arrays that grow - Use proper cache implementations
  2. Close resources - Database connections, file handles, etc.
  3. Unset large variables - Help PHP’s garbage collector
  4. Use dependency injection - Avoid globals and static state
  5. Monitor memory usage - Set up alerts for memory growth

Starting the Server

Command Line

This starts the server on port 8000 by default.

Custom Port

Programmatic

Stopping the Server

Press Ctrl+C or send SIGTERM:
Programmatically:

Development vs Production

Development Mode

In development, you’ll want to reload code changes:
During development, restart the server when you change code. Use file watchers to automate this.

Production Mode

In production, the Always-Alive server shines:

Comparing to Other Solutions

Lyger provides RoadRunner/Swoole-like performance with much simpler architecture thanks to Rust FFI.

Troubleshooting

Server Won’t Start

Port Already in Use

Memory Growth

Monitor memory usage:
Set memory limit:

Next Steps

Architecture Overview

Understand the full system architecture

Rust FFI Integration

Learn how PHP talks to Rust

Zero-Copy Database

Optimize database operations

Routing

Build your application routes