Skip to main content

Parallel Contract Execution for Maximum Efficiency

Parallel execution calls multiple contracts simultaneously. Each call executes independently - if one fails, others continue.

Understanding Parallel Execution

Key characteristics:

  1. Simultaneous execution - All contracts called at once
  2. Independent results - Each succeeds/fails independently
  3. Faster completion - Limited by slowest call
  4. Array of results - Callback receives all results

Implementation

Handling Multiple Responses

Process an array of results:

Real-World Example: DeFi Portfolio

@call({})
get_portfolio_data({
user,
token_contract,
lending_contract,
staking_contract
}: {
user: AccountId;
token_contract: AccountId;
lending_contract: AccountId;
staking_contract: AccountId;
}) {
// Get balance
const balance_promise = NearPromise.new(token_contract)
.functionCall(
"ft_balance_of",
JSON.stringify({account_id: user}),
0n,
5_000_000_000_000n
);

// Get lending position
const lending_promise = NearPromise.new(lending_contract)
.functionCall(
"get_position",
JSON.stringify({account_id: user}),
0n,
10_000_000_000_000n
);

// Get staking rewards
const staking_promise = NearPromise.new(staking_contract)
.functionCall(
"get_rewards",
JSON.stringify({account_id: user}),
0n,
5_000_000_000_000n
);

// Execute all in parallel
return balance_promise
.and(lending_promise)
.and(staking_promise)
.then(
NearPromise.new(env.current_account_id())
.functionCall(
"portfolio_callback",
JSON.stringify({user}),
0n,
15_000_000_000_000n
)
);
}

@call({privateFunction: true})
portfolio_callback({user}: {user: AccountId}) {
const results = [];

for (let i = 0; i < 3; i++) {
const result = getValueFromPromise(i);
if (result.success) {
results.push(JSON.parse(result.value));
} else {
results.push(null); // Handle failure
}
}

return {
user,
balance: results[0],
lending: results[1],
staking: results[2]
};
}

Performance Benefits

Sequential: ~300ms (100ms × 3)
Parallel: ~100ms (limited by slowest)

Error Handling

// Graceful degradation
const results = {
balance: "0",
rewards: "0"
};

if (balance_result.success) {
results.balance = balance_result.value;
}
// Use defaults for failures

Testing Parallel Execution

# Test parallel calls
near contract call-function as-transaction xcc.YOUR_NAME.testnet multiple_contracts json-args '{}' prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' sign-as YOUR_ACCOUNT.testnet network-config testnet sign-with-keychain send

When to Use

Use Parallel When:Use Batch When:
Different contractsSame contract
Independent operationsSequential dependencies
Can handle partial failuresNeed atomic rollback
Performance criticalConsistency critical

Finally, let's cover testing and deployment!