Skip to content

FR: Add Firestore FieldValue.min() and FieldValue.max() for atomic numeric comparisons #9309

@rscotten

Description

@rscotten

Operating System

not relevant

Environment (if applicable)

not relevant

Firebase SDK Version

not relevant

Firebase SDK Product(s)

Firestore

Project Tooling

not relevant

Detailed Problem Description

✨ Feature Request: Add FieldValue.min() and FieldValue.max() for atomic numeric and timestamp comparisons

Background

Firestore provides several atomic field transformation helpers such as:

  • FieldValue.increment(n: number)
  • FieldValue.arrayUnion(...elements: any[])
  • FieldValue.arrayRemove(...elements: any[])

These allow developers to update documents without first fetching their current state, which prevents race conditions and reduces read costs.

For example, FieldValue.arrayUnion appends unique elements if they don’t already exist, and all of these helpers automatically create the field if it doesn’t yet exist.

This makes Firestore updates concise, atomic, and efficient.


Problem

There is currently no built-in way to perform atomic minimum or maximum updates on a field.

Developers must:

  1. Fetch the document,
  2. Compare the existing value with the new one client-side, and
  3. Write the result back.

This introduces both extra read costs and race condition risks in concurrent update scenarios.


Proposed Solution

Add two new atomic field transformations:

FieldValue.min(value)
FieldValue.max(value)

These would compare the provided value against the existing field value and update the field to the smaller or larger of the two.

If the field does not exist, Firestore should initialize it with the provided value (consistent with existing FieldValue semantics).


Use Case

I’m building an ecommerce SaaS platform for rental tracking.
Each inventory item tracks the timestamp of its last rental activity:

item.lastActivityAt = <timestampMilliseconds>

The system must maintain this field as the latest known return date across thousands of concurrent rental line items.


Example

  • SKU with quantity = 2
  • One unit is rented this morning for 10 weeks (return date = +10 weeks)
  • Another unit is rented this afternoon for 1 week

Without atomic max support:

  • The later update (1-week rental) could overwrite the earlier one (10-week rental) if both updates happen close together.

The correct logic should be:

item.lastActivityAt = max(existingValue, newReturnDate)

Currently, this requires a fetch-compare-update cycle for every line item, which is both costly and inefficient:

  • ~10,000 line items processed per day → ~10,000 extra reads
  • Higher latency and risk of stale writes

Benefits

  • Enables atomic max() and min() updates similar to increment()
  • Avoids race conditions in concurrent write scenarios
  • Reduces read/write load by eliminating the need to prefetch documents
  • Applies broadly across use cases:
    • Tracking latest timestamps (lastSeenAt, lastLoginAt, etc.)
    • Maintaining running bounds (minPrice, maxTemperature, etc.)
    • Recording latest event times (latestUpdateAt, lastActivityAt, etc.)
  • Keeps Firestore’s expressive and consistent update API style

Suggested API

await docRef.update({
  lastActivityAt: FieldValue.max(newReturnDate)
});

Alternative Considered

Using Cloud Functions or a scheduled reconciliation process to serialize updates and compute maxima server-side.

However, this approach introduces latency, cost, and code complexity.

Having a server-side atomic comparison primitive would be faster, cheaper, and more reliable.


Summary

Adding FieldValue.max() and FieldValue.min() would be a natural and powerful extension of Firestore’s atomic update family.

It would dramatically simplify code, reduce operational costs, and prevent concurrency bugs for developers managing high-volume, multi-writer workloads.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions