The key thing is that a GET request should never change the application state from the perspective of the end user – however it can make changes on the backend that are not visible to the user. RFC7231 discusses what the restrictions on GET (and other “safe” methods) are:
Request methods are considered “safe” if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. Likewise, reasonable use of a safe method is not expected to cause any harm, loss of property, or unusual burden on the origin server.
This definition of safe methods does not prevent an implementation from including behavior that is potentially harmful, that is not entirely read-only, or that causes side effects while invoking a safe method. What is important, however, is that the client did not request that additional behavior and cannot be held accountable for it. For example, most servers append request information to access log files at the completion of every response, regardless of the method, and that is considered safe even though the log storage might become full and crash the server. Likewise, a safe request initiated by selecting an advertisement on the Web will often have the side effect of charging an advertising account.
Just like every GET request made to you site will result in an entry being written to your log files, it’s also perfectly acceptable for you to write an entry to your database for specific GET requests. However, in doing this, you might run into some unexpected requests being made with the UTM tags, such as:
- The user clicking the back button in their browser or refreshing the page.
- The user bookmarking a page with a UTM tag.
- A spider (such as Googlebot or a security scanning tool) crawling your website.
- A browser pre-fetching links on the page.
- The contents of the page being cached by the user or an intermediate proxy.
This could result in duplicate or spurious entries in your tracking database, and then are your problem to deal with, not the fault of your users.