Idempotence in Math and Programming: Testing Idempotency

Lecture



Idempotence (Lat. idem — the same + potens — capable) — the property of an object or operation whereby applying the operation to the object again yields the same result as the first application. The term was proposed by the American mathematician Benjamin Peirce in articles from the 1870s.

If a message is naturally idempotent, then processing the message several times results in the same value, for example, f (x) = f (f (x)).

Examples of idempotent operations:

  • adding zero: Idempotence in Math and Programming: Testing Idempotency;
  • multiplying by one: Idempotence in Math and Programming: Testing Idempotency;
  • the absolute value of a number: Idempotence in Math and Programming: Testing Idempotency;
  • selecting the maximum value: Idempotence in Math and Programming: Testing Idempotency;
  • computing the greatest common divisor: Idempotence in Math and Programming: Testing Idempotency;
  • addition modulo 2 with zero: Idempotence in Math and Programming: Testing Idempotency;
  • finding the remainder of division: Idempotence in Math and Programming: Testing Idempotency;
  • raising one to a power: Idempotence in Math and Programming: Testing Idempotency.

Element

An idempotent element (idempotent) in algebra — an element of a semigroup that is preserved when multiplied by itself: Idempotence in Math and Programming: Testing Idempotency. The idempotent theorem states: a finite semigroup contains an idempotent.

An idempotent element Idempotence in Math and Programming: Testing Idempotency contains an idempotent element Idempotence in Math and Programming: Testing Idempotency (denoted Idempotence in Math and Programming: Testing Idempotency), if Idempotence in Math and Programming: Testing Idempotency. The relation Idempotence in Math and Programming: Testing Idempotency is a partial-order relation on the set Idempotence in Math and Programming: Testing Idempotency of idempotent elements and is called the natural partial order on the set Idempotence in Math and Programming: Testing Idempotency.

Two idempotent elements of an associative ring (which is a semigroup under multiplication) Idempotence in Math and Programming: Testing Idempotency and Idempotence in Math and Programming: Testing Idempotency are called orthogonal if Idempotence in Math and Programming: Testing Idempotency.

Operation Idempotent matrix

An idempotent binary operation in mathematics — an operation with respect to which every element possesses idempotence in the above sense:

Idempotence in Math and Programming: Testing Idempotency.

This property is possessed, for example, by logical AND and logical OR.

An idempotent unary operation — an operation for which Idempotence in Math and Programming: Testing Idempotency holds, or Idempotence in Math and Programming: Testing Idempotency.

Among the linear operators in Idempotence in Math and Programming: Testing Idempotency, only the identity operator, the zero operator, and parallel projection are idempotent. Therefore, a projector in algebra — including in infinite-dimensional spaces — is defined as Idempotence in Math and Programming: Testing Idempotency.

In computer science and programming

An idempotent operation in computer science — an action whose repeated performance is equivalent to performing it once.

An example of such an operation is GET requests in the HTTP protocol. According to the specification, the server must return identical responses to identical GET requests (provided the resource has not changed). This allows these responses to be cached correctly, reducing the load on the network.

For the C language preprocessor, the directive «#include "xxx.h"» is idempotent if the header file has protection against double inclusion.

In computer science, the term idempotence can have different meanings depending on the context in which it is applied:

  • in imperative programming, a subroutine with side effects is idempotent if the state of the system remains unchanged after one or more calls; in other words, if the function from the system's state space into itself associated with the subroutine is idempotent in the mathematical sense given in the definition;
  • in functional programming, a pure function is idempotent if it is idempotent in the mathematical sense given in the definition.

This is a very useful property in many situations, since it means that an operation can be repeated as many times as necessary without causing unforeseen effects. With non-idempotent operations, the algorithm may have to track whether the operation has already been performed or not.

Examples from computer science

A function that looks up a customer's name and address in a database is usually idempotent, since it does not change the database. Similarly, changing a customer's address to XYZ is usually idempotent, because the final address will be the same no matter how many times XYZ is submitted. However, placing an order in a customer's cart is usually not idempotent, since making the call several times will result in several orders being placed. Cancelling an order is idempotent, because the order remains cancelled regardless of the number of requests made.

However, the composition of idempotent methods or subroutines is not necessarily idempotent if a later method in the sequence changes a value on which an earlier method depends — idempotence is not closed under composition. For example, suppose the initial value of a variable is 3, and there is a sequence that reads the variable, then changes it to 5, and then reads it again. Each step in the sequence is idempotent: both steps that read the variable have no side effects, and changing the variable to 5 will always have the same effect regardless of how many times it is performed. Nevertheless, executing the entire sequence once yields the result (3, 5), while executing it again yields the result (5, 5), so the sequence is not idempotent.

In the Hypertext Transfer Protocol (HTTP), idempotence and safety are the main attributes that distinguish HTTP verbs. Of the main HTTP verbs, GET, PUT, and DELETE must be implemented in an idempotent manner according to the standard, but POST does not have to be. [15] GET retrieves a resource; PUT stores content on a resource; and DELETE removes a resource. As in the example above, reading data usually has no side effects, so it is idempotent (in fact, nullipotent). Storing and deleting a given set of content are usually idempotent if the request specifies a location or identifier that uniquely identifies that resource and only that resource in the future. PUT and DELETE operations with unique identifiers reduce to the simple case of assigning either a value or a null value to an immutable variable, respectively, and are idempotent for the same reason; the final result is always the same as the result of the initial execution, even if the response differs.

Violating the unique-identification requirement when storing or deleting usually causes idempotence to be broken. For example, storing or deleting a given set of content without specifying a unique identifier: POST requests, which do not have to be idempotent, often do not contain unique identifiers, so creating the identifier is delegated to the receiving system, which then creates the corresponding new record. Similarly, PUT and DELETE requests with non-specific criteria may lead to different results depending on the state of the system — for example, a request to delete the most recent record. In each case, subsequent executions will further change the state of the system, so they will not be idempotent.

In event stream processing, idempotence refers to the ability of a system to produce the same result even if the same file, event, or message has been received more than once.

In a load-store architecture, instructions that can cause a page fault are idempotent. Thus, if a page fault occurs, the OS can load the page from disk and then simply re-execute the faulting instruction. In a processor where such instructions are not idempotent, handling page faults is much more complex.

When reformatting output, a pretty printer is expected to be idempotent. In other words, if the result is already «pretty», then the pretty printer itself has nothing to do.

In a service-oriented architecture (SOA), a multi-step orchestration process consisting entirely of idempotent steps can be replayed without side effects if any part of that process fails.

Many idempotent operations often have ways to «resume» a process if it was interrupted — ways that finish much faster than starting everything from the very beginning. For example, resuming a file transfer, file synchronization, creating a software build, installing an application and all its dependencies with a package manager, and so on.

Testing idempotence

Idempotence means that performing the same operation several times in a row will have the same effect as performing it once.

For example, setting the variable x to 5 is idempotent. You can set x to 5 once or a million times. It will still be 5. However, incrementing X by 1 is not idempotent. Each successive increment changes its value. Idempotence is a very desirable property in distributed systems with temporary network partitions and recovery protocols that retry sending a message several times if there is no immediate response.

If you build idempotence into your data-access code, you must test it. This is usually very simple. For each idempotent operation, you run the operation twice or more in a row and verify that there are no errors and that the state remains the same.

Note that an idempotent design can sometimes hide errors. Consider deleting a record from the DB. This is an idempotent operation. After a record is deleted, it no longer exists in the system, and attempting to delete it again will not bring it back. This means that attempting to delete a nonexistent record is a valid operation. But this can hide the fact that the caller passed the wrong record key. If you return an error message, then it is not idempotent.

Developing a feature is software development, and software must necessarily go through a testing stage; it is an integral part of the SDLC (Software Development Life Cycle).

Roles can be tested in different ways. Here are the scenarios I have encountered personally:

  • No testing at all — the worst option. We have no confidence that after making changes the feature will continue to work or will work the way we expect it to. You wrote or took someone's feature and simply use it, fixing all the problems that arise along the way.
  • One-time manual testing when making changes. Each time you make a change to a feature, you run it manually or with some automation. For example, on a virtual machine installed on your computer. This option is viable, but ideally you should test all possible usage scenarios of the role under the conditions of your infrastructure. This introduces significant overhead and does not allow you to verify the idempotence of the role.
  • Manual or automated checking of a role for idempotence. We test that your feature not only works, but also does not introduce any additional changes when run again. Better, of course, in automated mode. For example, hook up CI that will run the test on every change.
  • Automated testing of idempotence and various execution conditions of a role. Roughly the same as above, but taking into account the specifics of the environment. For example, considering the use of several kinds and versions of an operating system distribution, and different versions of packages. Here you cannot do without automation, because checking each change manually in such a case is too labor-intensive.
  • Automated testing of idempotence, application conditions, and execution results of a role. All the same as in the previous option, but with verification of the actual result. A feature that ran successfully does not guarantee that the service will start after it is changed. What if you made a typo in the configuration-file template or forgot to add an action to set the correct set of permissions for files? This, in my opinion, is the most complete and correct kind of testing, but at the same time the most expensive.


At first, you can use an inexpensive option: for each role we made a run on a test entity that reproduced an analogous entity in the live environment and was as similar to it as possible. This is implemented on the basis of Docker containers. We take a feature, run it for each kind of OS in parallel, and see that it ran successfully and did not fail. We run it a second time to make sure it is idempotent and does not introduce additional changes. This is the simplest and cheapest testing that can be done. Yes, it is not ideal, but it already gives you confidence that the feature will complete successfully and can be applied repeatedly to existing resources without the risk of breaking anything.

Idempotence in Math and Programming: Testing Idempotency

We did not want to run these tests manually. We have long used CI for rolling out Terraform changes, and we decided that a computer would handle the testing. But how do you automate this so that everything not directly related to developing the action role is done by a computer rather than a person?

On every commit pushed to the GitLab server, a simple pipeline runs that tests the changed feature. When an engineer wants to make a change to a feature, they create a new branch for the change, write the code, commit the changes, and push to the server. On the server, an event triggers a pipeline that consists of at least three stages:

  • First comes lint (static code analysis) — it checks the correctness of the syntax, conformance to best practices, and the absence of obvious errors and discrepancies.
  • The second step — a test of error-free application of the role and re-application with idempotence testing, as described above.
  • The third step — running additional tests. For example, not installing a package on a clean system, but upgrading or downgrading, removing a package, or installing without configuration.

Applied examples

Idempotence in Math and Programming: Testing Idempotency
A typical pedestrian crossing button — an example of an idempotent system.

Applied examples that many people may encounter in their everyday life include elevator call buttons and pedestrian crossing buttons. The initial press of the button puts the system into a requested state until the request is satisfied. Subsequent activations of the button between the initial activation and the satisfaction of the request have no effect, unless the system is designed to adjust the time for satisfying the request based on the number of activations.

See also

  • Maroon set
  • idempotency pattern
  • Closure operator
  • Fixed point (mathematics)
  • Code idempotence
  • Idempotent analysis
  • Idempotent matrix
  • Idempotent relation — a generalization of idempotence to binary relations
  • Involution (mathematics)
  • Iterated function
  • List of matrices
  • Nilpotent
  • Pure function
  • Referential transparency
created: 2021-10-22
updated: 2026-03-09
372



Was this answer useful?
Choose a quick rating so we can improve the next answer for you.
How satisfied are you?


Comments

To leave a comment

If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Lectures and tutorial on "Software and information systems development"

Terms: Software and information systems development