Skip to content
GigadriveDocs

Runtimes

The runtime identifiers Gigadrive Network accepts, what each one runs, and how the runtime decides the shape of your code.

A runtime pins the language and major version a Function executes under. You set one per Function in gigadrive.yaml, and leaving it out gives you node-20.

Available runtimes

IdentifierRunsNotes
node-22Node.js 22What framework detection picks for JavaScript projects
node-20Node.js 20Used when runtime is omitted
node-18Node.js 18
node-16Node.js 16
bun-1Bun 1What framework detection picks for Elysia
php-84PHP 8.4What framework detection picks for PHP projects
php-83PHP 8.3
php-81PHP 8.1Deprecated: new deployments are refused
ruby-40Ruby 4.0
ruby-34Ruby 3.4What framework detection picks for Ruby projects that name no version
ruby-33Ruby 3.3Security fixes only, until March 2027

PHP 8.1 no longer receives security fixes, so a new deployment that asks for php-81 is refused. Move to php-84 or php-83.

Those eleven strings are the whole set. Any other value fails config validation, so a typo such as node22 stops the deploy instead of surfacing when the first request arrives.

Patch releases

When a runtime gets a patch release, such as a Node.js, PHP or Ruby security release, deployments already running on that runtime move to it on their own once it is ready to serve, with nothing to redeploy. A copy of your Function that is already running keeps its release until it stops, and every copy started after the move runs the patch release. The same happens after a platform update to a runtime: a deployment made while the updated runtime was still being prepared starts on the previous one and moves to the update once it is ready. Only patch releases move a running deployment: a new minor or major version, such as Bun 1.3 to 1.4, takes effect with your next deployment, and so does any patch release for a Function with a sidecar next to it.

Pinning a runtime

runtime is a per-Function setting, keyed by the pattern that selects the file:

version: 4

functions:
  api/index.js:
    runtime: node-22
    memory: 512
  legacy/report.php:
    runtime: php-84

A project with no gigadrive.yaml gets its runtime from framework detection. Next.js, Nuxt, SvelteKit, Astro, Remix, NestJS, Express, Fastify, Hono and Vite all resolve to node-22; Elysia resolves to bun-1; Laravel, Symfony, CakePHP, CodeIgniter, Laminas, Mezzio, Slim, Yii 2 and any other PHP project resolve to php-84. Rails, Hanami, Sinatra, Roda, Jekyll, Bridgetown and any other project with a Gemfile resolve to the Ruby version the project names, read from .ruby-version, .tool-versions, the ruby line in the Gemfile or the RUBY VERSION in Gemfile.lock, and to ruby-34 when it names none. A version older than 3.3 runs on ruby-33, and a requirement such as ~> 3.3 runs on the newest Ruby it allows.

A PHP project with a composer.json runs on php-84 when its require.php constraint allows PHP 8.4, and otherwise on php-83 when the constraint allows PHP 8.3, such as ~8.3.0 or >=8.1 <8.4. A project with no require.php, a constraint Gigadrive Network cannot read, or one that allows neither version runs on php-84.

What the runtime expects from your code

A Node or Bun Function can take one of two shapes, and the platform picks between them by looking at what your entry file does when it loads.

Server-style. Your code creates an HTTP server: Express, Fastify, NestJS, Hono, or raw node:http. Requests are proxied straight to it. Bytes pass through untouched, and an Upgrade request is tunnelled to your server so it performs the WebSocket handshake itself. Frameworks that ship a Node server work with no adapter.

Handler-style. Your code exports a fetch function, or a (event, context) handler. Each request is re-framed into an event, your handler runs once, and the response it returns goes back to the client. A handler-style Function cannot accept a WebSocket upgrade; the connection is refused with 426.

A crash surfaces differently in each shape. A handler that throws returns 500 with a JSON body of {"errorMessage": "..."}. A server-style Function returns whatever its framework returns, and only when the server stops answering at all does the platform step in with a plain-text 502. Neither case kills the process.

PHP runs on php-fpm behind a FastCGI bridge, which serves the conventional front-controller layout without an adapter. Point a Function at public/index.php and the framework takes it from there.

A GET or HEAD request for a file that exists in the Function's directory is answered with that file before PHP runs, the way try_files works on nginx. This is how a file your application writes there at runtime reaches the browser, such as the CSS and JavaScript bundles Yii 2 publishes to web/assets. PHP scripts, files and directories whose name starts with a dot, such as .env and .htaccess, and files larger than 8 MB always go to PHP instead. Every other path reaches your front controller as before.

PHP Functions run with production settings: errors go to the logs rather than into the response, a fatal error returns 500, and OPcache is on. Because a deployment never changes, OPcache does not re-check file timestamps. A request body can be up to 6 MB, which is also the upload limit for a single file.

Besides the core extensions, both PHP runtimes include apcu, bcmath, calendar, curl, exif, gd (with JPEG, WebP and FreeType), gmp, intl, mbstring, mysqli, opcache, pdo_mysql, pdo_pgsql, pdo_sqlite, pgsql, redis, sockets, sodium, xsl and zip. Treat apcu as a local cache that can be empty on any request, and keep shared state such as sessions in Redis or a database. Requests made over HTTPS reach PHP with HTTPS set to on, so frameworks build https:// URLs without trusting a proxy header.

What changes for a PHP application

A PHP Function runs as one or more copies that start and stop with traffic, rather than on one long-lived server. Most applications need no change for that, but a few habits do:

  • Sessions. Each copy has its own files, so file-based sessions, the default in CakePHP, CodeIgniter, Symfony and Yii, only last while a visitor keeps reaching the same copy. Once your application runs more than one copy, store sessions in a database or a Redis server, or in cookies where the framework supports it. The Laravel preset uses cookie sessions for this reason.
  • Files you write at runtime. Caches, compiled templates and logs written inside your project stay with that copy and are gone when it stops. Keep anything that must last in a database, a cache server or File Storage.
  • Background work. Nothing runs php artisan queue:work, messenger:consume or schedule:run for you. Dispatch jobs synchronously (the Laravel preset sets QUEUE_CONNECTION=sync), or expose the work on a protected route and call it from an external scheduler. A cron job can also call your application on a schedule; it reaches the Function's root route with an x-nebula-cron: true header, which your front controller can check before running scheduled work.
  • Database migrations. A deployment never runs them. Run them yourself before or after deploying, against the database your application uses.
  • Responses. A PHP response is sent once it is complete, so streamed output, such as server-sent events, arrives all at once.
  • CakePHP's debug mode. The CakePHP preset sets DEBUG=false, so a deployment runs out of debug mode. To turn it on for an environment, set DEBUG to true under Environment variables.
  • CodeIgniter's baseURL. CodeIgniter builds links from its configured base URL, which defaults to http://localhost:8080/. Set app_baseURL to your site's address under Environment variables.

Ruby

A Ruby Function serves a Rack application, so Rails, Hanami, Sinatra, Roda, Grape and anything else with a config.ru run without an adapter. The Function's entrypoint is the config.ru; a classic Sinatra application without one can point at its script, such as app.rb. Gigadrive Network starts the application on Puma, using the Puma in your Gemfile.lock when there is one and its own copy otherwise, and passes every request through to it unchanged. Server-sent events (text/event-stream) reach the client as your application writes them, and WebSocket upgrades, such as Action Cable connections, reach your application as well.

Each copy of a Function runs one Puma process with five threads. Set RAILS_MAX_THREADS to change the thread count. Your config/puma.rb is not read: Gigadrive Network chooses the port and starts and stops the process itself.

The build installs your gems with Bundler into vendor/bundle, leaving out the development and test groups, and compiles native gems against the Ruby your Functions run on. When the Gemfile pins an exact patch release, such as ruby "3.3.6", the build runs it on the newest release of that Ruby version instead, because each Ruby runtime follows the newest patch release for its security fixes. After the gems are installed, the build runs bin/rails assets:precompile for a Rails application that uses Propshaft or Sprockets, hanami assets compile for Hanami, jekyll build for Jekyll and bridgetown deploy for Bridgetown, and runs a build script from package.json first when there is one.

Every Ruby runtime includes YJIT, which is switched on once your application has loaded (set RUBY_YJIT_ENABLE=0 to turn it off), the time zone database, and the shared libraries the common native gems need: PostgreSQL (pg), MySQL and MariaDB (mysql2, trilogy), SQLite (sqlite3), nokogiri and psych. Image processing libraries such as libvips are not included.

What changes for a Ruby application

As with PHP, a Ruby Function runs as one or more copies that start and stop with traffic:

  • SQLite. A Rails application whose database is SQLite, the default for a new Rails 8 application, gets its database created and its schema loaded when a copy starts. That database belongs to that copy alone and is gone when the copy stops, so it suits a demo, not real data. Point DATABASE_URL at a PostgreSQL or MySQL server for anything you need to keep. A server database is never migrated for you: run bin/rails db:migrate against it yourself.
  • Files you write at runtime. tmp/, log/ and storage/ are writable, but what lands there stays with one copy. Active Storage files belong in File Storage through its S3-compatible API.
  • Background work. Nothing runs Solid Queue, Sidekiq or a scheduler process for you. Run jobs inline or in a separate worker you host, or trigger the work on a schedule with a cron job.
  • Credentials. The Rails preset generates SECRET_KEY_BASE for each environment. If your application reads encrypted credentials, store RAILS_MASTER_KEY under Environment variables.

Runtime choice does not affect memory and CPU, which are set separately.