{"id":46775,"date":"2023-09-13T00:00:00","date_gmt":"2023-09-13T07:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/"},"modified":"2025-11-13T12:56:43","modified_gmt":"2025-11-13T20:56:43","slug":"realtime-event-tracking-using-spring-boot-and-griddb","status":"publish","type":"post","link":"https:\/\/griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/","title":{"rendered":"Realtime Event Tracking using Spring Boot and GridDB"},"content":{"rendered":"<h2>Definition of Event Tracking Service<\/h2>\n<p>In today&#8217;s digital landscape, tracking and analyzing user events is crucial for gaining insights into user behavior, optimizing performance, and delivering a personalized user experience.<\/p>\n<p>An event is any interaction occurring on a website or mobile app that is triggered by a user&#8217;s action. This includes a whole bunch of things from clicking a button to signing up for a newsletter to buying a product. Event page views themselves are events.<\/p>\n<p>An Event Tracking Service allows organizations to capture and process events as they happen, providing businesses with up-to-the-minute insights. This allows businesses to react swiftly to emerging trends, identify issues in real time, and make data-driven decisions on the fly.<\/p>\n<p>This article will explore how to implement a Realtime Event Tracking Service using Spring Boot and GridDB.<\/p>\n<h2>Functional Requirements<\/h2>\n<p>Before diving into the technical details, let&#8217;s outline the key functional requirements of our Event Tracking Service. These requirements will shape the design and implementation of our system.<\/p>\n<ul>\n<li>Capture and store events in real time.<\/li>\n<li>Provide a dashboard with aggregated data.<\/li>\n<\/ul>\n<h2>Estimating Capacity<\/h2>\n<p>Let&#8217;s find out how much data we need to process every day.<\/p>\n<p>Suppose, we have 10K daily active users.<br \/>\n* Each user has 50 clicks per day<br \/>\n* 10K * 50 = 500K clicks per day<br \/>\n* One-click data is 0.1KB<\/p>\n<p><em>Daily storage needed: 0.1KB * 500K = 50 megabytes per day<\/em><\/p>\n<h3>Choosing the Right Database: SQL or NoSQL<\/h3>\n<p>When it comes to databases, the choice between SQL and NoSQL depends on the specific requirements of your application. For our Realtime Event Tracking Service, where speed and scalability are crucial, NoSQL architecture outshines traditional SQL databases.<\/p>\n<p>NoSQL databases like GridDB provide flexible schema design, horizontal scalability, and optimized performance for handling high-volume, real-time event data. They offer fast data ingestion and retrieval, making them ideal for event tracking and analytics use cases.<\/p>\n<h2>Setting up a Java Application using Spring Boot<\/h2>\n<p>Before diving into the implementation details in Spring Boot, it&#8217;s important to have a basic understanding of the Spring Boot framework. Spring Boot is a popular Java-based framework that simplifies the development of standalone, production-grade Spring-based applications. It provides a comprehensive set of tools and libraries that streamline the development process, allowing developers to focus on writing business logic rather than dealing with boilerplate code.<\/p>\n<p>Now let&#8217;s proceed with setting up a Java application using Spring Boot.<\/p>\n<ul>\n<li>Install Java Development Kit (JDK) and set up your development environment.<\/li>\n<li>Set up a new Spring Boot project using your preferred build tool (e.g., Maven or Gradle).<br \/>\nWe will use https:\/\/start.spring.io\/ to initialize a Spring Boot project.<\/li>\n<li>Configure Spring Boot dependencies for GridDB and other required libraries.<br \/>\nThe main library in this project are :<\/p>\n<ol>\n<li><strong>spring-boot-starter-web<\/strong>: Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">    &lt;dependency&gt;\n        &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n        &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;<\/code><\/pre>\n<\/div>\n<ol>\n<li><strong>gridstore<\/strong> Java Client for GridDB CE<\/li>\n<\/ol>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">    &lt;dependency&gt;\n        &lt;groupId&gt;com.github.griddb&lt;\/groupId&gt;\n        &lt;artifactId&gt;gridstore&lt;\/artifactId&gt;\n        &lt;version&gt;5.1.0&lt;\/version&gt;\n    &lt;\/dependency&gt;<\/code><\/pre>\n<\/div>\n<h3>Define GridDB configurations<\/h3>\n<p>Before creating the API endpoint, we need to acquire a connection between the application and the cluster database of GridDB. Here we create an instance of GridStore class.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">@Bean\npublic GridStore gridStore() throws GSException {\n    \/\/ Acquiring a GridStore instance\n    Properties properties = new Properties();\n    properties.setProperty(\"notificationMember\", \"griddbserver:10001\");\n    properties.setProperty(\"clusterName\", \"dockerGridDB\");\n    properties.setProperty(\"user\", \"admin\");\n    properties.setProperty(\"password\", \"admin\");\n    GridStore store = GridStoreFactory.getInstance().getGridStore(properties);\n    return store;\n}<\/code><\/pre>\n<\/div>\n<h3>Implement event data models<\/h3>\n<p>This is our Java class that will hold the event data. We set the timestamp column as the primary key.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">import java.util.Date;\nimport com.toshiba.mwcloud.gs.RowKey;\nimport lombok.Data;\n\n@Data\npublic class Event {\n    @RowKey\n    Date timestamp;\n    String appId;\n    String eventType;\n    String externalId;\n}<\/code><\/pre>\n<\/div>\n<ul>\n<li>appId: Owner ID of the Mobile App or Website.<\/li>\n<li>eventType: &#8220;ADD_CART&#8221;, &#8220;ADD_TO_WISHLIST&#8221;, &#8220;IN_APP_AD_CLICK&#8221;, &#8220;SEARCH&#8221;, &#8220;LOGIN&#8221;, &#8220;LAUNCH_APP&#8221;, &#8220;START_TRIAL&#8221;<\/li>\n<li>externalId: External userId<\/li>\n<\/ul>\n<h3>Create a Container for managing the rows<\/h3>\n<p>After setting up the DB connection, we can use it to create the container. We are using the TimeSeries container to store a series of events because we need to manage rows with the occurrence time.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">import com.toshiba.mwcloud.gs.TimeSeries;\n\n@Bean\npublic TimeSeries<Event> eventsContainer(GridStore gridStore) throws GSException {\n    return gridStore.putTimeSeries(\"events\", Event.class);\n}<\/code><\/pre>\n<\/div>\n<ul>\n<li>com.toshiba.mwcloud.gs.TimeSeries interface is A specialized Container with a time-type Row key for TimeSeries data operation.<\/li>\n<\/ul>\n<h2>Capturing events.<\/h2>\n<p>We need to create RESTful endpoints for capturing events. In this tutorial, we only provide one endpoint.<\/p>\n<p>To report an event (e.g. <strong>LaunchAPP, Purchase, Login, Add to Cart<\/strong>), make a POST request through the \/app\/track\/ endpoint.<\/p>\n<pre><code>| Request address | http:\/\/localhost:8080\/api\/track |\n| -------- | -------- |\n| Request method     | **POST**     |\n\nRequest Example\n<\/code><\/pre>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">curl --request POST --url http:\/\/localhost:8080\/api\/track \n --header 'content-type: application\/json'  --header 'user-agent: vscode-restclient' \n   --data '{\n    \"appId\":\"APP_1\",\n    \"eventType\":\"ADD_CART\",\n    \"externalId\":\"2385254254\",\n    \"timestamp\":\"2023-07-12T10:55:50.764Z\"\n}'<\/code><\/pre>\n<\/div>\n<pre><code>Response Example\nHTTPS\/1.1 200 OK\nSaved\n<\/code><\/pre>\n<ul>\n<li>This endpoint will return an HTPP Status 200 on success, or throw an exception in case an error occurred.<\/li>\n<\/ul>\n<h3>Implement event processing and storage logic using GridDB&#8217;s Java client libraries<\/h3>\n<p>To save the event data, first, we need to acquire the Container created earlier, then call the append method.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">public void create(EventRequest request) {\n    Event event = new Event();\n    event.setAppId(request.getAppId());\n    event.setEventType(request.getEventType());\n    event.setExternalId(request.getExternalId());\n    event.setTimestamp(request.getTimestamp());\n    try {\n        eventsContainer.append(event);\n    } catch (GSException e) {\n        e.printStackTrace();\n    }\n}<\/code><\/pre>\n<\/div>\n<h2>Reporting Web Interface<\/h2>\n<p>Now we need to provide real-time dashboards. In this tutorial, we will create two charts to display the count of events by date and by event type.<\/p>\n<h3>Create chart<\/h3>\n<p>We use Chartjs to display the chart on top of the Thymeleaf template.<\/p>\n<p>Chart.js provides a set of frequently used chart types, plugins, and customization options. In addition to a reasonable set of built-in chart types, you can use additional community-maintained chart types. On top of that, it\u00e2\u0080\u0099s possible to combine several chart types into a mixed chart (essentially, blending multiple chart types into one on the same canvas).<\/p>\n<h4>We create a bar chart for a single dataset and render it on an HTML page.<\/h4>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">&lt;script th_inline=\"javascript\"&gt;\n    Chart.register(ChartDataLabels);\n    const ctx = document.getElementById('charts');\n\n    const data = \/*[[${aggregates}]]*\/[\n        { timeLabel: \"2023-07-01\", count: 10 }\n    ];\n\n    new Chart(ctx, {\n        type: 'bar',\n        data: {\n            labels: data.map(row => row.timeLabel),\n            datasets: [{\n                label: 'Count by Date',\n                data: data.map(row => row.count),\n                borderWidth: 1\n            }]\n        },\n        options: {\n            scales: {\n                y: {\n                    beginAtZero: true\n                }\n            },\n            plugins: {\n                datalabels: {\n                    color: 'white',\n                    font: {\n                        weight: 'bold'\n                    }\n                }\n            }\n        }\n    });<\/code><\/pre>\n<\/div>\n<h4>Showing the count of events by date<\/h4>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/09\/griddb-event-tracking1.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/09\/griddb-event-tracking1.png\" alt=\"\" width=\"941\" height=\"630\" class=\"aligncenter size-full wp-image-29783\" srcset=\"\/wp-content\/uploads\/2023\/09\/griddb-event-tracking1.png 941w, \/wp-content\/uploads\/2023\/09\/griddb-event-tracking1-300x201.png 300w, \/wp-content\/uploads\/2023\/09\/griddb-event-tracking1-768x514.png 768w, \/wp-content\/uploads\/2023\/09\/griddb-event-tracking1-600x402.png 600w\" sizes=\"(max-width: 941px) 100vw, 941px\" \/><\/a><\/p>\n<h4>Showing the count of events by event type<\/h4>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/09\/griddb-event-tracking2.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/09\/griddb-event-tracking2.png\" alt=\"\" width=\"918\" height=\"477\" class=\"aligncenter size-full wp-image-29781\" srcset=\"\/wp-content\/uploads\/2023\/09\/griddb-event-tracking2.png 918w, \/wp-content\/uploads\/2023\/09\/griddb-event-tracking2-300x156.png 300w, \/wp-content\/uploads\/2023\/09\/griddb-event-tracking2-768x399.png 768w, \/wp-content\/uploads\/2023\/09\/griddb-event-tracking2-600x312.png 600w\" sizes=\"(max-width: 918px) 100vw, 918px\" \/><\/a><\/p>\n<h3>Event aggregation<\/h3>\n<p>To provide the dataset into the chartjs, we need to use aggregate operation on the timeseries rows.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">public List<EventAggregateView> getEvents() {\n    List<EventAggregateView> views = new ArrayList<>();\n\n    LocalDateTime startDate = LocalDateTime.parse(\"2023-07-01T00:00:00\"),\n            endDate = LocalDateTime.now();\n    for (LocalDateTime date = startDate; date.isBefore(endDate); date = date.plusDays(1)) {\n        try {\n            java.util.Date start =\n                    convertToDateViaInstant(date.withHour(0).withMinute(0).withSecond(0));\n            java.util.Date end =\n                    convertToDateViaInstant(date.withHour(23).withMinute(59).withSecond(59));\n            AggregationResult aggregationResult =\n                    eventsContainer.aggregate(start, end, \"appId\", Aggregation.COUNT);\n            Long count = aggregationResult.getLong();\n            if (count.compareTo(0L) > 0) {\n                views.add(new EventAggregateView(convertToDateViaInstant(date), count,\n                        date.format(dateTimeFormatter)));\n            }\n        } catch (GSException e) {\n            e.printStackTrace();\n        }\n    }\n    return views;\n}<\/code><\/pre>\n<\/div>\n<p>We use the aggregate function from the TimeSeries container.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">AggregationResult aggregate(java.util.Date start,\n                          java.util.Date end,\n                          java.lang.String column,\n                          Aggregation aggregation)\n                            throws GSException<\/code><\/pre>\n<\/div>\n<blockquote>\n<p>Performs an aggregation operation on a Row set or its specific Columns, based on the specified start and end times.<br \/>\n  The parameter column might be ignored depending on the parameter aggregation. The boundary Rows whose timestamps are identical with the start or end time are included in the range of operation. If the specified start time is later than the end time, all Rows are excluded from the range.<\/p>\n<\/blockquote>\n<h3>For simulating the event creation, we create a scheduled task that will fire every minute.<\/h3>\n<div class=\"clipboard\">\n<pre><code class=\"language-java\">@Scheduled(fixedDelay = 1, initialDelay = 1, timeUnit = TimeUnit.MINUTES)\npublic void scheduleEventCreation() throws IOException, InterruptedException {\n    log.info(\"scheduleEventCreation()\");\n\n    HttpClient client = HttpClient.newHttpClient();\n    ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();\n\n    for (int i = 0; i <= 10; i++) {\n        Runnable runnableTask = () -> {\n            try {\n                postEvent(client);\n            } catch (IOException | InterruptedException e) {\n                e.printStackTrace();\n            }\n        };\n        executorService.schedule(runnableTask, i, TimeUnit.SECONDS);\n    }\n}\n\nprivate void postEvent(HttpClient client)\n        throws JsonProcessingException, IOException, InterruptedException {\n    Instant instant = Instant.now();\n    var values = new HashMap<String, String>() {\n        {\n            put(\"appId\", \"APP_1\");\n            put(\"eventType\", getRandomElement(EventTrackerConstants.EVENT_TYPE_LIST));\n            put(\"externalId\", faker.idNumber().valid());\n            put(\"timestamp\", instant.toString());\n        }\n    };\n\n    var objectMapper = new ObjectMapper();\n    String requestBody = objectMapper.writeValueAsString(values);\n\n    HttpRequest request =\n            HttpRequest.newBuilder().uri(URI.create(\"http:\/\/localhost:8080\/api\/track\"))\n                    .POST(HttpRequest.BodyPublishers.ofString(requestBody))\n                    .header(\"Content-type\", \"application\/json\").build();\n\n    client.send(request, HttpResponse.BodyHandlers.ofString());\n}<\/code><\/pre>\n<\/div>\n<h3>Running the Project with Docker Compose<\/h3>\n<p>To spin up the project we will utilize docker and docker-compose. We only need to install docker. Then run the following commands:<br \/>\n1. Build the docker image:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">docker compose build<\/code><\/pre>\n<\/div>\n<ol>\n<li>Run the docker image:<\/li>\n<\/ol>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">docker compose up<\/code><\/pre>\n<\/div>\n<h4>To see all events, open http:\/\/localhost:8080\/events<\/h4>\n<h4>To see the chart, open http:\/\/localhost:8080\/aggregate<\/h4>\n<h2>Best Practices<\/h2>\n<p>To make the most out of real-time event tracking in Spring Boot, it&#8217;s important to follow some best practices. Here are some recommendations to help you leverage the full potential of real-time event tracking:<\/p>\n<ul>\n<li>Spend time defining a clear and consistent event schema that captures all the relevant user actions and interactions. It&#8217;s also important to capture relevant contextual information that provides insights into the user&#8217;s state and environment.<\/li>\n<li>Ensure the system complies with data protection regulations and implement appropriate security measures.<\/li>\n<li>Implement analytics pipelines by using a stream processing engine.<\/li>\n<li>Decoupling event producer and consumer by using a combination of event-driven architectures and messaging technologies such as Apache Kafka or RabbitMQ.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Definition of Event Tracking Service In today&#8217;s digital landscape, tracking and analyzing user events is crucial for gaining insights into user behavior, optimizing performance, and delivering a personalized user experience. An event is any interaction occurring on a website or mobile app that is triggered by a user&#8217;s action. This includes a whole bunch of [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":29782,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46775","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Realtime Event Tracking using Spring Boot and GridDB | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"Definition of Event Tracking Service In today&#039;s digital landscape, tracking and analyzing user events is crucial for gaining insights into user behavior,\" \/>\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.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Realtime Event Tracking using Spring Boot and GridDB | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"Definition of Event Tracking Service In today&#039;s digital landscape, tracking and analyzing user events is crucial for gaining insights into user behavior,\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-13T07:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-13T20:56:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"891\" \/>\n\t<meta property=\"og:image:height\" content=\"543\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"griddb-admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"griddb-admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"Realtime Event Tracking using Spring Boot and GridDB\",\"datePublished\":\"2023-09-13T07:00:00+00:00\",\"dateModified\":\"2025-11-13T20:56:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/\"},\"wordCount\":1130,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/\",\"url\":\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/\",\"name\":\"Realtime Event Tracking using Spring Boot and GridDB | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg\",\"datePublished\":\"2023-09-13T07:00:00+00:00\",\"dateModified\":\"2025-11-13T20:56:43+00:00\",\"description\":\"Definition of Event Tracking Service In today's digital landscape, tracking and analyzing user events is crucial for gaining insights into user behavior,\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg\",\"contentUrl\":\"\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg\",\"width\":891,\"height\":543},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"caption\":\"griddb-admin\"},\"url\":\"https:\/\/griddb.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Realtime Event Tracking using Spring Boot and GridDB | GridDB: Open Source Time Series Database for IoT","description":"Definition of Event Tracking Service In today's digital landscape, tracking and analyzing user events is crucial for gaining insights into user behavior,","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.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/","og_locale":"en_US","og_type":"article","og_title":"Realtime Event Tracking using Spring Boot and GridDB | GridDB: Open Source Time Series Database for IoT","og_description":"Definition of Event Tracking Service In today's digital landscape, tracking and analyzing user events is crucial for gaining insights into user behavior,","og_url":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2023-09-13T07:00:00+00:00","article_modified_time":"2025-11-13T20:56:43+00:00","og_image":[{"width":891,"height":543,"url":"https:\/\/griddb.net\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg","type":"image\/jpeg"}],"author":"griddb-admin","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"griddb-admin","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#article","isPartOf":{"@id":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/"},"author":{"name":"griddb-admin","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"Realtime Event Tracking using Spring Boot and GridDB","datePublished":"2023-09-13T07:00:00+00:00","dateModified":"2025-11-13T20:56:43+00:00","mainEntityOfPage":{"@id":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/"},"wordCount":1130,"commentCount":0,"publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"image":{"@id":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/","url":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/","name":"Realtime Event Tracking using Spring Boot and GridDB | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#primaryimage"},"image":{"@id":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg","datePublished":"2023-09-13T07:00:00+00:00","dateModified":"2025-11-13T20:56:43+00:00","description":"Definition of Event Tracking Service In today's digital landscape, tracking and analyzing user events is crucial for gaining insights into user behavior,","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.net\/en\/blog\/realtime-event-tracking-using-spring-boot-and-griddb\/#primaryimage","url":"\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg","contentUrl":"\/wp-content\/uploads\/2023\/09\/system-design-event-tracking.jpg","width":891,"height":543},{"@type":"WebSite","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","caption":"griddb-admin"},"url":"https:\/\/griddb.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts\/46775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/comments?post=46775"}],"version-history":[{"count":1,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts\/46775\/revisions"}],"predecessor-version":[{"id":51441,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts\/46775\/revisions\/51441"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/media\/29782"}],"wp:attachment":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/media?parent=46775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/categories?post=46775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/tags?post=46775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}