{"id":1327,"date":"2023-02-07T09:43:57","date_gmt":"2023-02-07T09:43:57","guid":{"rendered":"https:\/\/infobip.com\/developers\/?p=1327"},"modified":"2023-09-11T14:31:27","modified_gmt":"2023-09-11T14:31:27","slug":"time-is-relative-according-to-my-database","status":"publish","type":"post","link":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database","title":{"rendered":"Time is relative, according to my database"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-1024x576.png\" alt=\"An image of clocks and universe\" class=\"wp-image-2092\" srcset=\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-1024x576.png 1024w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-300x169.png 300w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-768x432.png 768w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-1536x864.png 1536w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>According to special relativity, time is relative, meaning it depends on the speed of the observer.&nbsp;<\/p>\n\n\n\n<p>My PostgreSQL database instance, storing purchase history, would also agree that <strong>the timestamps it stores are relative<\/strong>, even though it is sitting still inside a well-cooled Data Center, not moving an inch. <\/p>\n\n\n\n<p>Even more so, my Postgres instance would absurdly agree that <strong>the arrow of time can be reversed, and things can be deleted even before they are created.&nbsp;<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Source of truth<\/strong>&nbsp;<\/h2>\n\n\n\n<p>I know you don\u2019t believe me \u2013 I didn\u2019t believe my own eyes when I first looked at the data in my tables. Staring back at me was an events table claiming <strong>that a shopping cart was purchased (deleted) even before it was created and filled with shopping items.<\/strong> <\/p>\n\n\n\n<p>That cannot be, since for it to be purchased, a shopping cart must be referenced by its ID, the one that comes into existence only after the shopping cart is created in the first place.&nbsp;<\/p>\n\n\n\n<p>For something that should be a source of truth, this database was pretty insincere.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Code doesn\u2019t lie<\/strong>&nbsp;<\/h2>\n\n\n\n<p>We decided to take a step back and investigate. There must be a reasonable explanation. We probably have some well-disguised bug.&nbsp;&nbsp;<\/p>\n\n\n\n<p>We looked at the backend logic first. As soon as the user clicked \u201cPurchase,\u201d a request was sent to the backend to process the purchase. The backend opens a transaction, checks if the shopping cart already exists in the database, and creates it if it doesn\u2019t. Afterward, the backend associates items the user selected with the newly created shopping cart. The last step of the transaction is for the backend to change the state of the shopping cart from CREATED to PURCHASED.&nbsp;&nbsp;<\/p>\n\n\n\n<p>All these inserts and updates to the shopping_cart table have a FOR EACH ROW trigger defined, which inserts those events into the shopping_cart_event table, <strong>together with the timestamp denoting when the trigger was executed.&nbsp;<\/strong>&nbsp;<\/p>\n\n\n\n<p>These events are periodically emptied and sent to another service for reporting purposes. Only the latest event for each cart is sent, which you might guess was problematic in this case, <strong>as the latest event wasn\u2019t the PURCHASED event, but CREATED event.&nbsp;<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Does the SQL lie?<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Judging by the Java code, everything checked out. But maybe the tear in the space-time continuum could somehow have been caused by Postgres, or to be more exact, by our SQL code.&nbsp;&nbsp;<\/p>\n\n\n\n<p>We looked closely at the SQL procedures that are called upon creation and consequent trigger execution. By examining the procedures, we couldn\u2019t spot anything suspicious. When we analyzed the triggers carefully, however, we noticed that<strong> calls which should retrieve the timestamp before events are inserted in the database are different.<\/strong> <\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-sql\" data-lang=\"SQL\"><code>CREATE TRIGGER shooping_cart_insert\n    AFTER INSERT ON shopping_cart\n    REFERENCING OLD TABLE AS old_table\n        NEW TABLE AS new_table\n    FOR EACH STATEMENT\nEXECUTE PROCEDURE on_shopping_cart_insert();\n\nCREATE OR REPLACE FUNCTION on_shopping_cart_insert() RETURNS TRIGGER AS $$\nBEGIN\n    INSERT INTO shopping_cart_event (id, event_type, event_timestamp)\n    SELECT id, &#39;CREATED&#39;, clock_timestamp()\n    FROM new_table;\n\n    RETURN NEW;\nEND; $$\nLANGUAGE plpgsql;<\/code><\/pre><\/div>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-sql\" data-lang=\"SQL\"><code>CREATE TRIGGER shooping_cart_update\n    AFTER UPDATE ON shopping_cart\n    REFERENCING OLD TABLE AS old_table\n        NEW TABLE AS new_table\n    FOR EACH STATEMENT\nEXECUTE PROCEDURE on_shopping_cart_update();\n\nCREATE OR REPLACE FUNCTION on_shopping_cart_update() RETURNS TRIGGER AS $$\nBEGIN\n    INSERT INTO shopping_cart_event (id, event_type, event_timestamp)\n    SELECT id, &#39;PURCHASED&#39;, now()\n    FROM new_table\n    WHERE purchased = true;\n\n    RETURN NEW;\nEND; $$\nLANGUAGE plpgsql;<\/code><\/pre><\/div>\n\n\n\n<p>The calls are: <strong>clock_timestamp()<\/strong> and <strong>now()<\/strong>. Hmm, let\u2019s see what the official <a href=\"https:\/\/www.postgresql.org\/docs\/current\/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT\" target=\"_blank\" rel=\"noreferrer noopener\">Postgres documentation <\/a>tells us.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" src=\"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2023\/02\/white-timestamp.png\" alt=\"\" class=\"wp-image-1428\" style=\"width:750px\" width=\"750\" srcset=\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/02\/white-timestamp.png 936w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/02\/white-timestamp-300x43.png 300w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/02\/white-timestamp-768x110.png 768w\" sizes=\"(max-width: 936px) 100vw, 936px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" src=\"https:\/\/infobip.com\/developers\/wp-content\/uploads\/2023\/02\/white-timestamp-2.png\" alt=\"\" class=\"wp-image-1429\" style=\"width:750px\" width=\"750\" srcset=\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/02\/white-timestamp-2.png 936w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/02\/white-timestamp-2-300x43.png 300w, https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/02\/white-timestamp-2-768x110.png 768w\" sizes=\"(max-width: 936px) 100vw, 936px\" \/><\/figure>\n\n\n\n<p>Oh, did you catch that subtle difference? One actually returns <strong>the current timestamp from the system<\/strong>, and the other <strong>takes the timestamp from the start of the transaction.&nbsp;&nbsp;<\/strong><\/p>\n\n\n\n<p>INSERT trigger is calling clock_timestamp(), which returns the current system time, <strong>regardless of when the transaction began<\/strong>. But the UPDATE trigger is calling now(), which will return<strong> the time at the start of the current transaction.&nbsp;<\/strong>&nbsp;<\/p>\n\n\n\n<p>As we know, triggers are executed in the same transaction as the statement which triggered them. This means that even though the UPDATE trigger was executed after the INSERT trigger, its timestamp will be before the INSERT timestamp.&nbsp;&nbsp;<\/p>\n\n\n\n<p>And once the events are collected and prepared to be sent to the other service, only the latest event, which is INSERT according to the timestamps, will be sent to the service. We, too, were baffled when we realized this was the root cause of all our problems.&nbsp;&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>The truth<\/strong>&nbsp;<\/h2>\n\n\n\n<p>In the end, it seems that Postgres didn\u2019t care about special relativity and wasn\u2019t lying to us; <strong>it has done exactly what we told it to do.<\/strong> We were lying to ourselves, thinking that clock_timestamp and now() are working in the same fashion.&nbsp;&nbsp;<\/p>\n\n\n\n<p>And to be clear, the exact situation in our case was a bit more complex, and no web shops were involved, but carts were more illustrative than actual events.<\/p>\n\n\n\n<p>In summary, always be careful and think twice before fetching the current timestamp<strong>.<\/strong> I<strong>f you need the current timestamp to be the same throughout the transaction, use now().<\/strong> But if you need <strong>the exact timestamp when a command was executed within the transaction, use clock_timestamp()<\/strong>. We\u2019ve learned a valuable lesson here, and we hope that you do too.&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>According to special relativity, time is relative. My Postgres instance would agree and elaborate that things can be deleted even before they are created.\u00a0<\/p>\n","protected":false},"author":22,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[28,249,254,252],"tags":[260,47],"coauthors":[167],"class_list":["post-1327","post","type-post","status-publish","format-standard","hentry","category-blog-post","category-devops-and-security","category-engineering-practices","category-tools","tag-architecture","tag-data"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Time is relative, according to my database<\/title>\n<meta name=\"description\" content=\"Or how we discovered that clock_timestamp() and now() were making a tear in the space time continuum (or at leat in our reporting).\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Time is relative, according to my database\" \/>\n<meta property=\"og:description\" content=\"Or how we discovered that clock_timestamp() and now() were making a tear in the space time continuum (or at leat in our reporting).\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database\" \/>\n<meta property=\"og:site_name\" content=\"Infobip Developers Hub\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/infobip\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-07T09:43:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-11T14:31:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-1024x576.png\" \/>\n<meta name=\"author\" content=\"Anton Filipovic\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@InfobipDev\" \/>\n<meta name=\"twitter:site\" content=\"@InfobipDev\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Anton Filipovic\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database\"},\"author\":{\"name\":\"Anton Filipovic\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/04389666425c8b0d0769d687685fa831\"},\"headline\":\"Time is relative, according to my database\",\"datePublished\":\"2023-02-07T09:43:57+00:00\",\"dateModified\":\"2023-09-11T14:31:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database\"},\"wordCount\":793,\"publisher\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-1024x576.png\",\"keywords\":[\"architecture\",\"data\"],\"articleSection\":[\"Blog Post\",\"DevOps and Security\",\"Engineering Practices\",\"Tools\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database\",\"url\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database\",\"name\":\"Time is relative, according to my database\",\"isPartOf\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-1024x576.png\",\"datePublished\":\"2023-02-07T09:43:57+00:00\",\"dateModified\":\"2023-09-11T14:31:27+00:00\",\"description\":\"Or how we discovered that clock_timestamp() and now() were making a tear in the space time continuum (or at leat in our reporting).\",\"breadcrumb\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#primaryimage\",\"url\":\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1.png\",\"contentUrl\":\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1.png\",\"width\":1920,\"height\":1080},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.infobip.com\/developers\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Time is relative, according to my database\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#website\",\"url\":\"https:\/\/www.infobip.com\/developers\/\",\"name\":\"Infobip Developers Hub\",\"description\":\"Build meaningful customer relationships across any channel\",\"publisher\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.infobip.com\/developers\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#organization\",\"name\":\"Infobip Developers Hub\",\"url\":\"https:\/\/www.infobip.com\/developers\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/03\/Infobip_logo_favicon.png\",\"contentUrl\":\"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/03\/Infobip_logo_favicon.png\",\"width\":696,\"height\":696,\"caption\":\"Infobip Developers Hub\"},\"image\":{\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/infobip\/\",\"https:\/\/x.com\/InfobipDev\",\"https:\/\/www.youtube.com\/channel\/UCUPSTy53VecI5GIir3J3ZbQ\",\"https:\/\/github.com\/infobip-community\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/04389666425c8b0d0769d687685fa831\",\"name\":\"Anton Filipovic\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/image\/6bcc8046026fcb16a985a4c23b9c6082\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5a98ac6d226b3fd434f5c9b8d963a1b4906609c7a847dec98f5109e02c9226e4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5a98ac6d226b3fd434f5c9b8d963a1b4906609c7a847dec98f5109e02c9226e4?s=96&d=mm&r=g\",\"caption\":\"Anton Filipovic\"},\"description\":\"Full stack software engineer working at Infobip since 2019, specializes in the SMS Firewall domain. In addition to his passion for coding, he is an avid enthusiast of nature, outdoor activities and sports, with a particular fondness for both indoor and beach volleyball.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/anton-filipovic\/\"],\"url\":\"https:\/\/www.infobip.com\/developers\/blog\/author\/anton-filipovic\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Time is relative, according to my database","description":"Or how we discovered that clock_timestamp() and now() were making a tear in the space time continuum (or at leat in our reporting).","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database","og_locale":"en_US","og_type":"article","og_title":"Time is relative, according to my database","og_description":"Or how we discovered that clock_timestamp() and now() were making a tear in the space time continuum (or at leat in our reporting).","og_url":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database","og_site_name":"Infobip Developers Hub","article_publisher":"https:\/\/www.facebook.com\/infobip\/","article_published_time":"2023-02-07T09:43:57+00:00","article_modified_time":"2023-09-11T14:31:27+00:00","og_image":[{"url":"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-1024x576.png","type":"","width":"","height":""}],"author":"Anton Filipovic","twitter_card":"summary_large_image","twitter_creator":"@InfobipDev","twitter_site":"@InfobipDev","twitter_misc":{"Written by":"Anton Filipovic","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#article","isPartOf":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database"},"author":{"name":"Anton Filipovic","@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/04389666425c8b0d0769d687685fa831"},"headline":"Time is relative, according to my database","datePublished":"2023-02-07T09:43:57+00:00","dateModified":"2023-09-11T14:31:27+00:00","mainEntityOfPage":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database"},"wordCount":793,"publisher":{"@id":"https:\/\/www.infobip.com\/developers\/#organization"},"image":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#primaryimage"},"thumbnailUrl":"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-1024x576.png","keywords":["architecture","data"],"articleSection":["Blog Post","DevOps and Security","Engineering Practices","Tools"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database","url":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database","name":"Time is relative, according to my database","isPartOf":{"@id":"https:\/\/www.infobip.com\/developers\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#primaryimage"},"image":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#primaryimage"},"thumbnailUrl":"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1-1024x576.png","datePublished":"2023-02-07T09:43:57+00:00","dateModified":"2023-09-11T14:31:27+00:00","description":"Or how we discovered that clock_timestamp() and now() were making a tear in the space time continuum (or at leat in our reporting).","breadcrumb":{"@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#primaryimage","url":"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1.png","contentUrl":"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/04\/Untitled-design-2-1.png","width":1920,"height":1080},{"@type":"BreadcrumbList","@id":"https:\/\/www.infobip.com\/developers\/blog\/time-is-relative-according-to-my-database#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.infobip.com\/developers\/"},{"@type":"ListItem","position":2,"name":"Time is relative, according to my database"}]},{"@type":"WebSite","@id":"https:\/\/www.infobip.com\/developers\/#website","url":"https:\/\/www.infobip.com\/developers\/","name":"Infobip Developers Hub","description":"Build meaningful customer relationships across any channel","publisher":{"@id":"https:\/\/www.infobip.com\/developers\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.infobip.com\/developers\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.infobip.com\/developers\/#organization","name":"Infobip Developers Hub","url":"https:\/\/www.infobip.com\/developers\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/logo\/image\/","url":"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/03\/Infobip_logo_favicon.png","contentUrl":"https:\/\/www.infobip.com\/developers\/wp-content\/uploads\/2023\/03\/Infobip_logo_favicon.png","width":696,"height":696,"caption":"Infobip Developers Hub"},"image":{"@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/infobip\/","https:\/\/x.com\/InfobipDev","https:\/\/www.youtube.com\/channel\/UCUPSTy53VecI5GIir3J3ZbQ","https:\/\/github.com\/infobip-community"]},{"@type":"Person","@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/04389666425c8b0d0769d687685fa831","name":"Anton Filipovic","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.infobip.com\/developers\/#\/schema\/person\/image\/6bcc8046026fcb16a985a4c23b9c6082","url":"https:\/\/secure.gravatar.com\/avatar\/5a98ac6d226b3fd434f5c9b8d963a1b4906609c7a847dec98f5109e02c9226e4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5a98ac6d226b3fd434f5c9b8d963a1b4906609c7a847dec98f5109e02c9226e4?s=96&d=mm&r=g","caption":"Anton Filipovic"},"description":"Full stack software engineer working at Infobip since 2019, specializes in the SMS Firewall domain. In addition to his passion for coding, he is an avid enthusiast of nature, outdoor activities and sports, with a particular fondness for both indoor and beach volleyball.","sameAs":["https:\/\/www.linkedin.com\/in\/anton-filipovic\/"],"url":"https:\/\/www.infobip.com\/developers\/blog\/author\/anton-filipovic"}]}},"_links":{"self":[{"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/posts\/1327","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/users\/22"}],"replies":[{"embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/comments?post=1327"}],"version-history":[{"count":21,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/posts\/1327\/revisions"}],"predecessor-version":[{"id":2524,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/posts\/1327\/revisions\/2524"}],"wp:attachment":[{"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/media?parent=1327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/categories?post=1327"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/tags?post=1327"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.infobip.com\/developers\/wp-json\/wp\/v2\/coauthors?post=1327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}