Reusing an existing IMAP connection in a custom node to avoid connection limits

I’m developing a custom IMAP node and currently have it working, but I’ve run into an issue with IMAP connection limits.

The IMAP service I’m using blocks the client after a certain number of connections are opened in a short period of time.

My node includes a trigger that stays permanently connected to IMAP and uses a hybrid approach:

  • IDLE to detect new incoming emails

  • Polling to detect emails that are moved into specific folders

Since this trigger already maintains an active IMAP connection, I was wondering if it’s possible (or advisable) to reuse that existing connection for other IMAP operations.

In the same node, I also expose several actions, such as:

  • Move message to folder

  • Mark message as seen

At the moment, each of these actions opens a new IMAP connection, which quickly hits the provider’s connection limits.

My questions are:

  1. Is it possible to reuse the trigger’s existing IMAP connection for other operations within the same node?

  2. If so, what is the recommended pattern for sharing or managing a single IMAP connection across trigger logic and action executions?

Short answer: you can’t share the trigger connection with actions in n8n - they run in separate contexts.

But here’s a better solution that actually works:

Use connection pooling at the node level

Create a simple connection pool manager in your node:

class ImapConnectionPool {
  private static instance: ImapClient | null = null;
  private static lastUsed: number = 0;
  private static timeout = 5 * 60 * 1000; // 5 min

  static async getConnection(credentials) {
    const now = Date.now();
    
    // Reuse if still valid
    if (this.instance && (now - this.lastUsed) < this.timeout) {
      this.lastUsed = now;
      return this.instance;
    }
    
    // Create new connection
    this.instance = await createNewImapConnection(credentials);
    this.lastUsed = now;
    return this.instance;
  }
}

Then in your actions:

const connection = await ImapConnectionPool.getConnection(credentials);
await connection.moveMessage(...);
// Don't close - let the pool manage it

Why this works:

  • Reuses connections within a time window
  • Automatically creates new ones when needed
  • Respects IMAP provider limits

Alternative approach if your provider is super strict:

Batch your operations. Instead of:

  • Move message → close
  • Mark as seen → close

Do:

  • Open once → move message → mark as seen → close

I’ve built custom IMAP nodes for clients dealing with strict Office365 limits. Connection pooling solved it completely.

Happy to help if you need the full implementation!

Hi, Thanks for ur reply, for now i dont think it will be necessary. I had the flow working running over the weekend and the trigger mode was able to manage the emails. I will let it run like this and tell the customer the limitations. if they want me to develop further, i might take you up in that offer! :slight_smile:

Ah Perfect.