Skip to content

Representation of Monetary Amounts in Mojaloop as Integers Instead of Decimals #135

@vijayg10

Description

@vijayg10

Request Summary:

Should Mojaloop represent monetary amounts and position fields as integers (minor units per ISO 4217) instead of decimals, to improve accuracy and performance?

Request Details:

  • Deadline: -
  • Impact (Teams): Core Mojaloop developers, QA/testing, deployment/infra teams, API integrators (DFSPs, Hub Operators).
  • Impact (Components):
    • Mojaloop APIs (amount fields in schemas and position field in admin apis)
    • Central Ledger DB schema (amount, position fields)
    • ML-Number usage in services
    • API documentation & developer guides

Background:

Currently, Mojaloop represents monetary amounts as strings with decimal values (e.g., "10.99"). This requires string parsing and arithmetic through the ML-Number library.

However, handling decimals in software introduces precision issues and performance overhead. For example, in many languages:

print(0.1 + 0.2)  
# Output: 0.30000000000000004

This is not a bug, but a fundamental limitation of binary floating-point representation (IEEE 754) in computers.

  • Humans can represent 1/3 in base-10 decimals only as an approximation (e.g., 0.3333…). It’s a repeating decimal that cannot be expressed with finite precision in base-10.
  • Computers use base-2 (binary) floating-point. In the same way many decimal fractions (e.g., 0.1, 0.2) cannot be represented exactly in binary, leading to rounding errors.

While Mojaloop avoids direct floating-point usage by relying on ML-Number and string representations, this pushes the burden into software-emulated decimal operations, which are slower and less efficient than native CPU integer operations.

Industry Best Practice:

Financial systems commonly store amounts in integers (e.g., cents instead of dollars). This avoids floating-point pitfalls and simplifies comparisons, summations, and validations.

The ISO 4217 specification defines minor units for each currency (e.g., 2 decimal places for USD, 0 for JPY). By multiplying the amount by 10^minorUnits, we can store amounts as whole integers.

Proposed Change

  • Store all amounts (including position fields) as integers, scaled by ISO 4217 minor units.
    • Example: 10.99 USD1099 (cents).
  • Update API specifications to expect integer values.
  • Remove reliance on ML-Number for basic amount operations.
  • Update Mojaloop documentation to reflect this change.

Benefits

  • Accuracy: Removes rounding errors.
  • Performance: Leverages native CPU integer arithmetic.
  • Simplicity: Easier for developers to handle values consistently.
  • Consistency: Aligns Mojaloop with financial services industry best practices.

Risks & Considerations

  • Backward compatibility: Integrations expect string decimals. We may need API versioning or string conversions.
  • Currency variations: Some currencies have unusual minor units (e.g., 3 decimals for TND). Must ensure ISO 4217 mapping is consistently applied.
  • Migration effort: DB schema changes, API refactor, and integration testing required.

Next Steps

  1. Run a PoC refactor for one service to integer-based amounts.
  2. Benchmark performance: throughput, latency, CPU utilization (with vs. without ML-Number).
  3. Develop a migration strategy (DB, APIs, integration impacts).
  4. Present results for DA decision.

Artifacts:

  • Benchmark PoC results

Dependencies:

  • API versioning strategy
  • Migration path for existing integrations

Accountability:

  • Owner:
  • Raised By: Vijaya Kumar Guthi

Decision(s):

  • Approved By:

Details

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions