Transient data structures are mutable variants of the immutable data structures. They exist to serve high performance requirements that spring up as part of any large code-base, but are not intended to be shared between functions. A transient value should be created, mutated, and then converted to its immutable counterpart before being distributed to other parts of the system. Transient values allow for conventional algorithms, like quicksort, to exist in Clojure. They are not, however, intended to be used for ongoing, mutable data structures. Like a running index of searchable terms which is updated in place as new terms are added to the search space. In Clojure, these data structures are still intended to be built with persistent, immutable data structures.
Transients are created from persistent data structures, and continue to use those structures under the hood. This means creating a transient is an $O(1)$ operation, even if the underlying collection is large. From that point on, however, alterations to the transient must be made using mutation operations. These operations are different from the standard update operations which return a new immutable structure, but are generally presented as mutable analogs. For example,
conj (short for conjoin) creates a new vector with all the elements of an existing vector, plus additional elements. Whereas
conj! adds elements to a transient vector.