{"id":18432,"date":"2020-05-29T12:21:45","date_gmt":"2020-05-29T18:21:45","guid":{"rendered":"https:\/\/www.fullcontact.com\/?p=18432"},"modified":"2025-01-06T05:00:26","modified_gmt":"2025-01-06T12:00:26","slug":"resolve-building-the-identity-resolution-engine-part-4","status":"publish","type":"post","link":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/","title":{"rendered":"Resolve: Building the Identity Resolution Engine (Part 4)"},"content":{"rendered":"<p>The following is the fourth and final installment of a multi-part series offering a glimpse of the behind-the-scenes advancements we achieved to deliver our <a href=\"https:\/\/www.fullcontact.com\/products\/resolve\/\">Resolve<\/a>\u00a0API.\u00a0<a href=\"https:\/\/www.fullcontact.com\/blog\/2020\/05\/08\/resolve-building-the-identity-resolution-engine\/\">The first post\u00a0<\/a>covered the origin of our\u00a0<a href=\"https:\/\/www.fullcontact.com\/identity-graph\/\">Identity Graph<\/a> and Resolve API. In <a href=\"https:\/\/www.fullcontact.com\/blog\/2020\/05\/15\/resolve-building-the-identity-resolution-engine-part-2\/\">the second post<\/a>, we delved into the power of our new persistent PersonID and the ability to Bring Your Own ID. <a href=\"https:\/\/www.fullcontact.com\/blog\/2020\/05\/22\/resolve-building-the-identity-resolution-engine-part-3\/\">The third post <\/a>focused on building customer trust through security capabilities.<\/p>\n<h2>Part 4: Being API First and Choosing Our Bedrock<\/h2>\n<p><span style=\"font-weight: 400;\">As any structural engineer will tell you, having the proper foundation to build from is paramount to the success of a project. Designing and engineering scalable and performant APIs is no different&#8211;and if you\u2019re an API-First company like FullContact, you\u2019d better be good at it!<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The release of <a href=\"https:\/\/www.fullcontact.com\/products\/resolve\/\">Resolve<\/a> API and <a href=\"https:\/\/www.fullcontact.com\/maids\/\">MAID<\/a> capabilities are taking us into a new world inching closer to the realm of AdTech. Industry roughly dictates being able to sustain sub 80ms response time at high volumes, where the best can achieve 15ms and millions of requests a second.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To help us achieve these performance characteristics, we leverage Scala and Java8 for our APIs, DropWizard for the scaffolding, prefer asynchronous call flows with HTTP clients and Kafka, and utilize modern scalable databases such as Cassandra and HBase.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Generally, databases tend to be the primary source of bottlenecks and while we had used HBase for other systems and processes such as our <\/span><a href=\"https:\/\/www.fullcontact.com\/blog\/2019\/06\/27\/enrich-api-brings-higher-match-rates-with-multi-field-enrichment-capabilities\/\"><span style=\"font-weight: 400;\">Data Onlining and Enrichment services<\/span><\/a><span style=\"font-weight: 400;\">, we diversified and elected to move to Cassandra. Currently, we have Cassandra 3.11.5 powering our Resolve DB, and leverage Virtual Nodes (vnodes) to simplify our scaling procedures. Cassandra also offers simpler and familiar query syntax with CQL, and it\u2019s schema definitions allow clever and efficient ways to organize your data between partition and clustering keys. With Cassandra, it also has a more performant and theoretically \u201cSuper-charged Sister\u201d with <\/span><a href=\"https:\/\/www.scylladb.com\/\"><span style=\"font-weight: 400;\">Scylla<\/span><\/a><span style=\"font-weight: 400;\">, which could offer more headroom for shaving off millis.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Once we had the Resolve API assembled, we wanted to ensure we hit the targets we set out to achieve &#8211; benchmarking your API is the simplest way to understand these characteristics. Below summarizes a few results from Apache Benchmark on our Resolve API using pre-mapped RIDs as input to the <code>identity.resolve<\/code> endpoint. A key characteristic of each test is that it uses \u2018connection reuse\u2019 to avoid the costly SSL setup time.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The first test runs the test within an AWS region that our API is deployed, <\/span><span style=\"font-weight: 400;\">us-east1<\/span><span style=\"font-weight: 400;\"> in this case. The median latency was 22ms, and mean around 27ms.<img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-18433 aligncenter\" src=\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM-300x174.png\" alt=\"\" width=\"300\" height=\"174\" srcset=\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM-300x174.png 300w, https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM-1024x595.png 1024w, https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM-768x446.png 768w, https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM.png 1532w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/span><\/p>\n<p><span style=\"font-weight: 400;\">When benchmarked outside the walls of Amazon, it yields slower but still good performance where median latency was 79ms, and mean at 81ms.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-18434 aligncenter\" src=\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.03.42-PM-300x188.png\" alt=\"\" width=\"300\" height=\"188\" srcset=\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.03.42-PM-300x188.png 300w, https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.03.42-PM-1024x641.png 1024w, https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.03.42-PM-768x481.png 768w, https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.03.42-PM-1440x900.png 1440w, https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.03.42-PM.png 1536w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<h2>See It In Action<\/h2>\n<p><span style=\"font-weight: 400;\">To demonstrate a few simple examples with <code>curl<\/code>, we can display a common use case where a FullContact customer has two completely different systems. One system is a CRM managing all active customers, the other being a Loyalty Program system helping drive engagement with the brand. In this simple example, we load two systems into the Resolve API who are completely siloed from each other. Once loaded, the goal is to be able to better understand their customers. This example has an important \u201creal world\u201d twist where API is presented with an identifier that is currently unknown to the brand &#8211; the user\u2019s B2C email.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Load CRM DB records via <code>identity.map<\/code> and <code>recordID<\/code> with a Business Email:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">curl -s -HContent-Type:application\/json \\<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0-H\"Authorization: Bearer xxx\" \\<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0https:\/\/api.fullcontact.com\/v3\/<\/span>identity.map<span style=\"font-weight: 400;\"> \\<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0-d '{\"<\/span>&lt;recordId\":\"crm:12345<span style=\"font-weight: 400;\">\", \"emails\":[\"&lt; first.last@b2b.com<\/span><span style=\"font-weight: 400;\">\"]}'<\/span>\r\n\r\n<span style=\"font-weight: 400;\">{<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\"recordIds\": [<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\"<\/span>crm:12345<span style=\"font-weight: 400;\">\"<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0]<\/span>\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n\r\n\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">Load Rewards DB records via <code>identity.map<\/code> and <code>recordId<\/code> with a phone number:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">curl -s -HContent-Type:application\/json \\<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0-H\"Authorization: Bearer xxx\" \\<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0https:\/\/api.fullcontact.com\/v3\/<\/span>identity.map<span style=\"font-weight: 400;\"> \\<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0-d '{\"recordId\":\"<\/span>rewards:TS012FH2<span style=\"font-weight: 400;\">\", \"phone\":[\"<\/span>&lt;&gt;13032223333<span style=\"font-weight: 400;\">\"]}'<\/span>\r\n<span style=\"font-weight: 400;\">{<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\"recordIds\": [<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\"<\/span>rewards:TS012FH2<span style=\"font-weight: 400;\">\"<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0]<\/span>\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">During an event on either system, the consumer interacts with the brand using their consumer-based email, we can see that the user is both an active customer (from the CRM) and a rewards member:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">curl -s -HContent-Type:application\/json \\<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0-H\"Authorization: Bearer xxx\" \\<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0https:\/\/api.fullcontact.com\/v3\/<\/span>identity.resolve<span style=\"font-weight: 400;\"> \\<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0-d '{\"emails\":[\"first@gmail.com<\/span><span style=\"font-weight: 400;\">\"]}'<\/span>\r\n<span style=\"font-weight: 400;\">{<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\"recordIds\": [<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\"<\/span>crm:12345<span style=\"font-weight: 400;\">\",<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\"<\/span>rewards:TS012FH2<span style=\"font-weight: 400;\">\"<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0],<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\"personIds\": [<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0\u00a0\"R0kavZ-q79TRs6ySys-KhIhIzag7iZUcGkcupicq6P0_W8sX\"<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0]<\/span>\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">While not explicitly shown above the implied magic here is that <\/span>13032223333<span style=\"font-weight: 400;\">, <\/span><a href=\"mailto:first.last@b2b.com\">first.last@b2b.com<\/a><span style=\"font-weight: 400;\"> and <\/span><a href=\"mailto:first@gmail.com\">first@gmail.com<\/a><span style=\"font-weight: 400;\"> all share the <\/span><b>same<\/b> <strong>P<\/strong><b>ersonID. <\/b><span style=\"font-weight: 400;\">If queried individually in the <code>identity.resolve<\/code> endpoint, they all return the same <code>PersonID<\/code>. Not only that, but any identifier connected to the Person record will do the same, just as the <\/span><a href=\"mailto:first@gmail.com\">first@gmail.com<\/a><span style=\"font-weight: 400;\"> shows. This is where the Identity Graph showcases its true power!<\/span><\/p>\n<h2>Resolve: A Bright Star in the Making<\/h2>\n<p><span style=\"font-weight: 400;\">If you made it through the full series, I hope you gained some key takeaways that can be brought to the table on either the product or engineering side! I am greatly appreciative of the product and engineering teams for giving me the capability to write about the fantastic things we&#8217;re working on, and we hope you\u2019ll continue to follow us as we dive deeper into other technical issues. We&#8217;re just at the beginning of a new journey as we work to redefine the consumer and brand relationship in a positive, secure, and privacy-focused way.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If you\u2019re ever wondering about \u201cchanging it up\u201d, let us know! Our teams at FullContact are technical and have very challenging problems to solve and we are looking to add curious, hard-working collaborators who love solving hard problems!\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Post comments or questions as you have them, and follow our <\/span><a href=\"https:\/\/www.fullcontact.com\/careers\/\"><span style=\"font-weight: 400;\">careers page<\/span><\/a><span style=\"font-weight: 400;\"> as we open new roles! Thanks for reading!<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The following is the fourth and final installment of a multi-part series offering a glimpse of the behind-the-scenes advancements we achieved to deliver our Resolve\u00a0API.\u00a0The first post\u00a0covered the origin of our\u00a0Identity Graph and Resolve API. In the second post, we delved into the power of our new persistent PersonID and the ability to Bring Your [&hellip;]<\/p>\n","protected":false},"author":42,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_improvement_type_select":"improve_an_existing","_thumb_yes_seoaic":false,"_frame_yes_seoaic":false,"seoaic_generate_description":"","seoaic_improve_instructions_prompt":"","seoaic_rollback_content_improvement":"","seoaic_idea_thumbnail_generator":"","thumbnail_generated":false,"thumbnail_generate_prompt":"","seoaic_article_description":"","seoaic_article_subtitles":[],"footnotes":""},"categories":[679,656],"tags":[5663,5664,5665,5661,5662,5638,674,648,75,290,98,478,50],"class_list":["post-18432","post","type-post","status-publish","format-standard","hentry","category-resolve","category-engineering","tag-java8","tag-hbase","tag-dropwizard","tag-scylla","tag-scala","tag-personid","tag-resolve","tag-maids","tag-api-challenge","tag-identity-2","tag-identity-resolution","tag-identity-graph","tag-api"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.1 (Yoast SEO v27.1.1) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Resolve: Building the Identity Resolution Engine (Part 4) | FullContact<\/title>\n<meta name=\"description\" content=\"The following is the fourth and final installment of a multi-part series offering a glimpse of the behind-the-scenes advancements we achieved to deliver\" \/>\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.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Resolve: Building the Identity Resolution Engine (Part 4)\" \/>\n<meta property=\"og:description\" content=\"As any structural engineer will tell you, having the proper foundation to build from is paramount to the success of a project. Designing and engineering scalable and performant APIs is no different--and if you\u2019re an API-First company like FullContact, you\u2019d better be good at it!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/\" \/>\n<meta property=\"og:site_name\" content=\"FullContact\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-29T18:21:45+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-01-06T12:00:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/engineering-resolve-li.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Ken Michie\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/engineering-resolve-tw.png\" \/>\n<meta name=\"twitter:creator\" content=\"@fullcontact\" \/>\n<meta name=\"twitter:site\" content=\"@fullcontact\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ken Michie\" \/>\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.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/\"},\"author\":{\"name\":\"Ken Michie\",\"@id\":\"https:\/\/www.fullcontact.com\/#\/schema\/person\/763f69f799a4cd2a2188fea684c3f337\"},\"headline\":\"Resolve: Building the Identity Resolution Engine (Part 4)\",\"datePublished\":\"2020-05-29T18:21:45+00:00\",\"dateModified\":\"2025-01-06T12:00:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/\"},\"wordCount\":847,\"publisher\":{\"@id\":\"https:\/\/www.fullcontact.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM-300x174.png\",\"keywords\":[\"Java8\",\"HBase\",\"DropWizard\",\"Scylla\",\"Scala\",\"PersonID\",\"Resolve\",\"MAIDs\",\"api challenge\",\"identity\",\"identity resolution\",\"identity graph\",\"API\"],\"articleSection\":[\"Resolve\",\"Engineering\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/\",\"url\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/\",\"name\":\"Resolve: Building the Identity Resolution Engine (Part 4) | FullContact\",\"isPartOf\":{\"@id\":\"https:\/\/www.fullcontact.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM-300x174.png\",\"datePublished\":\"2020-05-29T18:21:45+00:00\",\"dateModified\":\"2025-01-06T12:00:26+00:00\",\"description\":\"The following is the fourth and final installment of a multi-part series offering a glimpse of the behind-the-scenes advancements we achieved to deliver\",\"breadcrumb\":{\"@id\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#primaryimage\",\"url\":\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM.png\",\"contentUrl\":\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM.png\",\"width\":1532,\"height\":890},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.fullcontact.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Resolve: Building the Identity Resolution Engine (Part 4)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.fullcontact.com\/#website\",\"url\":\"https:\/\/www.fullcontact.com\/\",\"name\":\"FullContact\",\"description\":\"Relationships, reimagined.\",\"publisher\":{\"@id\":\"https:\/\/www.fullcontact.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.fullcontact.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.fullcontact.com\/#organization\",\"name\":\"FullContact\",\"url\":\"https:\/\/www.fullcontact.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.fullcontact.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2019\/11\/fc-logo@2x.png\",\"contentUrl\":\"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2019\/11\/fc-logo@2x.png\",\"width\":200,\"height\":38,\"caption\":\"FullContact\"},\"image\":{\"@id\":\"https:\/\/www.fullcontact.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/fullcontact\",\"https:\/\/www.linkedin.com\/company\/fullcontact-inc-\",\"https:\/\/www.youtube.com\/user\/FullContactAPI\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.fullcontact.com\/#\/schema\/person\/763f69f799a4cd2a2188fea684c3f337\",\"name\":\"Ken Michie\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.fullcontact.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/59c32a659aa924a55d4df202ed7d2ddefc1aefe5a6e7b369e15a5c222fe58c93?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/59c32a659aa924a55d4df202ed7d2ddefc1aefe5a6e7b369e15a5c222fe58c93?s=96&d=mm&r=g\",\"caption\":\"Ken Michie\"},\"url\":\"https:\/\/www.fullcontact.com\/blog\/author\/kenmichie\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Resolve: Building the Identity Resolution Engine (Part 4) | FullContact","description":"The following is the fourth and final installment of a multi-part series offering a glimpse of the behind-the-scenes advancements we achieved to deliver","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.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/","og_locale":"en_US","og_type":"article","og_title":"Resolve: Building the Identity Resolution Engine (Part 4)","og_description":"As any structural engineer will tell you, having the proper foundation to build from is paramount to the success of a project. Designing and engineering scalable and performant APIs is no different--and if you\u2019re an API-First company like FullContact, you\u2019d better be good at it!","og_url":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/","og_site_name":"FullContact","article_published_time":"2020-05-29T18:21:45+00:00","article_modified_time":"2025-01-06T12:00:26+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/engineering-resolve-li.png","type":"image\/png"}],"author":"Ken Michie","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/engineering-resolve-tw.png","twitter_creator":"@fullcontact","twitter_site":"@fullcontact","twitter_misc":{"Written by":"Ken Michie","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#article","isPartOf":{"@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/"},"author":{"name":"Ken Michie","@id":"https:\/\/www.fullcontact.com\/#\/schema\/person\/763f69f799a4cd2a2188fea684c3f337"},"headline":"Resolve: Building the Identity Resolution Engine (Part 4)","datePublished":"2020-05-29T18:21:45+00:00","dateModified":"2025-01-06T12:00:26+00:00","mainEntityOfPage":{"@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/"},"wordCount":847,"publisher":{"@id":"https:\/\/www.fullcontact.com\/#organization"},"image":{"@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#primaryimage"},"thumbnailUrl":"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM-300x174.png","keywords":["Java8","HBase","DropWizard","Scylla","Scala","PersonID","Resolve","MAIDs","api challenge","identity","identity resolution","identity graph","API"],"articleSection":["Resolve","Engineering"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/","url":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/","name":"Resolve: Building the Identity Resolution Engine (Part 4) | FullContact","isPartOf":{"@id":"https:\/\/www.fullcontact.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#primaryimage"},"image":{"@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#primaryimage"},"thumbnailUrl":"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM-300x174.png","datePublished":"2020-05-29T18:21:45+00:00","dateModified":"2025-01-06T12:00:26+00:00","description":"The following is the fourth and final installment of a multi-part series offering a glimpse of the behind-the-scenes advancements we achieved to deliver","breadcrumb":{"@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#primaryimage","url":"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM.png","contentUrl":"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2020\/05\/Screen-Shot-2020-05-28-at-4.02.57-PM.png","width":1532,"height":890},{"@type":"BreadcrumbList","@id":"https:\/\/www.fullcontact.com\/blog\/resolve\/resolve-building-the-identity-resolution-engine-part-4\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.fullcontact.com\/"},{"@type":"ListItem","position":2,"name":"Resolve: Building the Identity Resolution Engine (Part 4)"}]},{"@type":"WebSite","@id":"https:\/\/www.fullcontact.com\/#website","url":"https:\/\/www.fullcontact.com\/","name":"FullContact","description":"Relationships, reimagined.","publisher":{"@id":"https:\/\/www.fullcontact.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.fullcontact.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.fullcontact.com\/#organization","name":"FullContact","url":"https:\/\/www.fullcontact.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.fullcontact.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2019\/11\/fc-logo@2x.png","contentUrl":"https:\/\/www.fullcontact.com\/wp-content\/uploads\/2019\/11\/fc-logo@2x.png","width":200,"height":38,"caption":"FullContact"},"image":{"@id":"https:\/\/www.fullcontact.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/fullcontact","https:\/\/www.linkedin.com\/company\/fullcontact-inc-","https:\/\/www.youtube.com\/user\/FullContactAPI"]},{"@type":"Person","@id":"https:\/\/www.fullcontact.com\/#\/schema\/person\/763f69f799a4cd2a2188fea684c3f337","name":"Ken Michie","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.fullcontact.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/59c32a659aa924a55d4df202ed7d2ddefc1aefe5a6e7b369e15a5c222fe58c93?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/59c32a659aa924a55d4df202ed7d2ddefc1aefe5a6e7b369e15a5c222fe58c93?s=96&d=mm&r=g","caption":"Ken Michie"},"url":"https:\/\/www.fullcontact.com\/blog\/author\/kenmichie\/"}]}},"_links":{"self":[{"href":"https:\/\/www.fullcontact.com\/wp-json\/wp\/v2\/posts\/18432","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fullcontact.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fullcontact.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fullcontact.com\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fullcontact.com\/wp-json\/wp\/v2\/comments?post=18432"}],"version-history":[{"count":0,"href":"https:\/\/www.fullcontact.com\/wp-json\/wp\/v2\/posts\/18432\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.fullcontact.com\/wp-json\/wp\/v2\/media?parent=18432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fullcontact.com\/wp-json\/wp\/v2\/categories?post=18432"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fullcontact.com\/wp-json\/wp\/v2\/tags?post=18432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}