This project is not covered by Drupal’s security advisory policy.

Description

The Persistent SMTP module significantly improves email sending performance in Drupal by maintaining persistent SMTP connections across multiple email sends within a single request, rather than opening and closing a new connection for each email.

This module is particularly beneficial for sites that send bulk emails, batch notifications, or process email queues, where the overhead of establishing new SMTP connections can severely impact performance.

Features

  • Connection Pooling: Reuses SMTP connections across multiple emails within the same request
  • Automatic Connection Management: Intelligently manages connection lifecycle with configurable limits
  • Smart Health Checking: Monitors connection health and automatically reconnects when needed
  • Performance Statistics: Tracks connection reuse rates and sending times for debugging
  • Clean Shutdown: Automatically closes connections at the end of each request to prevent resource leaks
  • Seamless Integration: Works with Symfony Mailer without requiring changes to existing email code
  • Zero Configuration: Works out of the box with sensible defaults

Requirements

Installation

Install the module using Composer:

composer require drupal/persistent_smtp

Enable the module:

drush en persistent_smtp -y

Clear cache:

drush cr

Configuration

The module works immediately after installation with default settings.

Advanced Configuration

For advanced configuration, add settings to your settings.php or settings.local.php file:

$settings['smtp_persistent_config'] = [
  // Maximum number of emails to send before reconnecting
  'max_messages_per_connection' => 100,

  // Maximum connection lifetime in seconds (5 minutes default)
  'max_connection_lifetime' => 300,

  // Keep connection alive between sends
  'keep_alive' => TRUE,
];

Disable Persistent Connections

To temporarily disable persistent connections (for debugging):

$config['symfony_mailer.settings']['use_persistent_smtp'] = FALSE;

Performance Benefits

In bulk email scenarios, this module can provide:

  • 50-80% reduction in total sending time for bulk emails
  • Reduced server load from fewer connection establishments
  • Lower latency per email in batch operations
  • Better throughput for queue-based email systems

Example Performance Comparison

Without Persistent SMTP:

  • Sending 100 emails: ~150 seconds
  • Each email requires: ~1.5 seconds (1.4s connection + 0.1s sending)

With Persistent SMTP:

  • Sending 100 emails: ~30 seconds
  • First email: ~1.5 seconds (connection + send)
  • Subsequent emails: ~0.1 seconds each (reusing connection)

How It Works

  1. First Email: When the first email is sent in a request, a persistent SMTP connection is established
  2. Connection Reuse: Subsequent emails within the same request reuse the existing connection
  3. Health Monitoring: The connection is monitored for health using NOOP commands
  4. Automatic Reconnection: If a connection becomes stale or unhealthy, it's automatically replaced
  5. Clean Shutdown: At the end of each request, all connections are gracefully closed via the KernelEvents::TERMINATE event

Use Cases

This module is ideal for:

  • Bulk Email Notifications: Sending notifications to multiple users
  • Queue-Based Processing: Processing email queues (e.g., cron jobs)
  • Batch Operations: Mass mailing campaigns
  • User Registration: Sites with high user registration rates
  • Event Notifications: Sending multiple notifications per event
  • Report Generation: Emailing reports to multiple recipients

Troubleshooting

Enable Debug Logging

To see timing information for email sends, enable verbose logging:

  1. Go to Configuration > Development > Logging and errors
  2. Set "Error messages to display" to "All messages, with backtrace information"

Or via Drush:

drush state:set system.logging_error_level verbose

Check Log Files

Monitor the persistent_smtp log channel:

drush watchdog:show --type=persistent_smtp

Common Issues

Connection Timeouts:

  • Increase max_connection_lifetime in settings
  • Check your SMTP server's connection timeout limits

Too Many Connections:

  • Reduce max_messages_per_connection in settings
  • Check SMTP server connection limits

Performance Not Improving:

  • Verify the module is enabled: drush pm:list --status=enabled | grep persistent_smtp
  • Check that use_persistent_smtp is not set to FALSE
  • Ensure you're sending multiple emails per request (not single emails)

Technical Details

Architecture

The module consists of:

  1. PersistentSmtpTransportFactory: Creates and manages persistent SMTP transport instances
  2. CustomTransportManager: Ensures the persistent SMTP factory is prioritized
  3. SmtpConnectionCleanupSubscriber: Handles connection cleanup at request termination
  4. PersistentSmtpServiceProvider: Alters the service container to use custom transport manager

Dependencies

The module integrates seamlessly with Symfony Mailer and provides:

  • Connection health checking (NOOP commands)
  • Automatic reconnection logic
  • Connection statistics tracking
  • Stream optimization

Events

  • KernelEvents::TERMINATE (Priority: -100): Used to close connections after response is sent to the client

Similar Modules

Project information

Releases