Faster Server Startup in Meteor 3.4 with Deferrables

Published: (February 12, 2026 at 05:01 PM EST)
3 min read
Source: Dev.to

Source: Dev.to

Introduction

Meteor 3.4 brings a major developer‑experience upgrade, including deferrable functions. They let you defer non‑critical asynchronous work until after the initial startup, speeding up local development cycles.

The deferrable API

import { Meteor } from "meteor/meteor";

Meteor.startup(async () => {
  await Meteor.deferrable(connectToExternalDB, {
    on: ["development"],
  });
});
  • On the specified environments (e.g., development), connectToExternalDB runs after the app has finished booting, instead of blocking startup.
  • You can target test, development, and production environments individually.

Helper Functions

deferDev

A convenience wrapper around deferrable for development (and test) environments.

const connectToExternalExpensiveService = async () => {
  const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
  console.log("Connecting to external expensive service...");
  await sleep(Math.random() * 2000 + 1000); // simulate expensive connection
  console.log("Connected to external expensive service!");
};

await Meteor.deferDev(connectToExternalExpensiveService);
  • Use this for any work that can be postponed while developing locally.
  • Consistent use often yields a ~2 s reduction in startup time.

deferProd

A similar wrapper for production environments, useful for one‑off cases such as warming caches or initializing analytics pipelines that aren’t needed for the first request.

Meteor.deferProd(async () => {
  console.log("Warming cache...");
  // perform production‑only initialization here
});

Execution Order

When a function is not deferred for the current environment, it runs immediately and returns values just like a normal call.

console.log("Before deferDev");
Meteor.deferDev(async () => {
  console.log("Connecting to some external service...");
  console.log("This will run later on local mode!");
});
console.log("After deferDev");

console.log("Before deferProd");
Meteor.deferProd(async () => {
  console.log("Connecting to some service...");
  console.log("This will run later on prod mode!");
});
console.log("After deferProd");

// Example output in a regular Meteor run:
// Before deferDev
// After deferDev
// Before deferProd
// Connecting to some service...
// This will run later on prod mode!
// After deferProd
// Connecting to some external service...
// This will run later on local mode!

Returning Values

Deferred functions can also return values:

const value = Meteor.deferDev(() => "later_in_dev") ||
              Meteor.deferProd(() => "later_in_prod");
console.log("value is set to:", value);

If the function isn’t deferred for the current environment, the returned value is used immediately.

Best Practices

  1. Identify slow startup work – external API calls, expensive DB connections, cache warm‑ups, etc.
  2. Wrap them with deferDev (or deferProd when appropriate).
  3. Measure the impact – most teams see noticeable improvements right away.
  4. Treat deferred work as part of your “startup hygiene”: anything that doesn’t affect correctness should be a candidate for deferral.

Real‑World Impact

  • The Galaxy team reported a ~3× faster local startup after applying these deferrals.
  • Teams that upgraded to Meteor 3.4 and adopted the API consistently saw a reduction of several seconds in startup time.

Getting Help

If you’re migrating to Meteor 3.4 and have questions, encounter edge cases, or want to share your results, join the discussion on the Meteor forums.


0 views
Back to Blog

Related posts

Read more »

Partial Indexes in PostgreSQL

Partial indexes are refined indexes that target specific access patterns. Instead of indexing every row in a table, they only index the rows that match a condit...