Fix: Salesforce “Login Rate Limit Exceeded” for Integration Users

Salesforce enforces a platform security threshold known as the Login Rate Limit, which restricts any single user account to 3,600 login requests per hour. When an automated integration, external service, or middleware tool initiates a new authentication handshake on every individual transaction instead of maintaining an active session, the platform rejects all incoming connections with the LOGIN_RATE_EXCEEDED error for that user.

Fast Fix

Update your external integration or middleware (e.g., MuleSoft, Zapier, custom scripts) to cache and reuse the OAuth access_token or API sessionId across transactions. An integration should authenticate once, store the session token for its full valid duration (typically 1 to 2 hours), and only re-authenticate when receiving an explicit 401 Unauthorized response.


Diagnostic Snapshot

  • Error Signatures: LOGIN_RATE_EXCEEDED, Login Rate Limit Exceeded, Remote host closed connection during handshake.
  • Platform Threshold: Exactly 3,600 login attempts per rolling 60-minute window per individual user account.
  • Affected Layers: SOAP API login() calls, REST OAuth token endpoints (/services/oauth2/token), and mobile SDK integrations.
  • Permissions Needed: System Administrator access to view Login History and modify Connected App session policies.

How the Login Rate Limit Operates

The Login Rate Limit is fundamentally different from your organization’s daily API call limit:

  • Daily API Limit: Governs the total number of REST/SOAP data operations (queries, inserts, updates) allowed across a rolling 24-hour window for the entire organization (often hundreds of thousands of calls).
  • Login Rate Limit: Governs authentication events specifically. Each execution of the SOAP login() method or each HTTP POST request to /services/oauth2/token counts as one login call.

If an integration script processes 5,000 records per hour and calls login() before uploading each individual record, it will trigger LOGIN_RATE_EXCEEDED after exactly 3,600 calls. For the remainder of that rolling hour, every connection attempt by that user will fail immediately.


Diagnostic Path

Integration Receives LOGIN_RATE_EXCEEDED
 ├── Check Setup ──► Login History
 │    ├── Filter by: User Name & Status = "Failed" / "Login Rate Exceeded"
 │    ├── Review: Application & Source IP columns
 │    └── Count: Are multiple client servers sharing one user account?
 └── Inspect Integration Middleware Architecture
      ├── Does the integration authenticate per call? ──► Implement session caching
      ├── Is a microservice pool scaling dynamically? ──► Implement centralized auth token broker
      └── Are credentials incorrect? ───────────────────► Halt retry storm

Step 1: Analyze Login History

  1. Log into Salesforce Setup.
  2. In the Quick Find box, type Login History and select it.
  3. Download the login records for the past 7 days as a CSV or create a view filtered by Status: Login Rate Limit Exceeded.
  4. Identify:
    • The User Name being blocked.
    • The Source IP generating the high request volume.
    • The Login Type (e.g., Application, Remote Access 2.0, or SOAP Web Services).

If multiple IP addresses appear under the same integration user name, separate middleware worker nodes are competing for authentication independently.


Step-by-Step Resolution

1. Implement Session and Token Caching

The most common cause of this error is treating the Salesforce API as stateless. Your external code or integration middleware must retain the authorization session token in memory or in an external cache (like Redis):

  1. Make the initial authentication request to Salesforce.
  2. Extract and store the access_token (or sessionId) and its expiration window.
  3. Pass that cached access_token in the HTTP Authorization header (Authorization: Bearer <token>) for all subsequent API requests.
  4. Catch 401 Unauthorized exceptions in your API client wrapper. Only when a 401 occurs should your client discard the token and request a new one.
// Node.js / Integration Token Caching Example
let cachedToken = null;

async function getValidToken() {
    if (!cachedToken) {
        // Authenticate only when token is missing or expired
        const authResponse = await authenticateWithSalesforce();
        cachedToken = authResponse.access_token;
    }
    return cachedToken;
}

async function sendDataToSalesforce(record) {
    let token = await getValidToken();
    try {
        await postRecord(record, token);
    } catch (error) {
        if (error.response && error.response.status === 401) {
            // Token expired; invalidate and re-authenticate once
            cachedToken = null;
            token = await getValidToken();
            await postRecord(record, token);
        } else {
            throw error;
        }
    }
}

2. Transition from SOAP login() to OAuth 2.0 JWT Bearer Flow

Legacy SOAP integrations frequently use hardcoded username/password combinations that call login() repeatedly. Modern integrations should utilize the OAuth 2.0 JWT Bearer Token Flow:

  • The client signs a JSON Web Token using a digital certificate.
  • Certificates eliminate password expiration issues.
  • Token lifespans are predictable and can be managed directly via Connected App policies in Salesforce Setup. If setting up or reconfiguring authorization handshakes, reference How to Resolve: Salesforce “Connected App” failing OIDC Handshakes.

3. Adjust Session Timeout Policies

Ensure that your Salesforce Connected App does not force unnecessarily short session timeouts:

  1. Go to Setup > App Manager.
  2. Locate the integration’s Connected App, click the dropdown menu, and select Manage.
  3. Click Edit Policies.
  4. Under Session Policies, review Timeout Value. Set it to a reasonable duration (e.g., 2 hours to 4 hours) rather than 15 minutes to reduce re-authentication frequency.

4. Stop Runaway Authentication Retries

When an integration user’s password expires or a security token changes, misconfigured scripts frequently enter an infinite retry loop—attempting to authenticate hundreds of times per minute.

  • Add an exponential backoff policy with a hard retry limit (e.g., maximum 3 attempts) in your integration code.
  • If three consecutive authentication attempts fail, halt the integration worker and alert administrators via system notification rather than spamming the authentication endpoint. For external connectors encountering authentication failures, see Fix: “Unauthorized” error in Zapier-to-Salesforce Connections.

Common Misdiagnoses

  • Confusing Login Limits with Daily API Limits: If integrations fail with REQUEST_LIMIT_EXCEEDED, you have exhausted your organization’s total 24-hour API call allocation. The Login Rate Limit strictly applies to the initial connection phase (LOGIN_RATE_EXCEEDED).
  • Profile-Level Login Hours / IP Ranges: If the login history shows Restricted IP or Invalid Login Hours, the user is not hitting the 3,600 hourly rate limit; they are failing security checks configured on their Profile. Confirm permissions using Fix: Salesforce “You do not have the required permissions” (Identity Loop).

Hard Stops

  • Never resolve this error by sharing a single integration account across multiple enterprise applications. Stacking ERP, marketing, and customer portal integrations onto one shared user compounds login rate usage and creates single-point-of-failure risks.
  • Create dedicated integration users for each separate external system. This isolates your hourly rate limits and provides clean audit trails in your setup logs.