diff --git a/backends/README.md b/backends/README.md
index 7218ff6ed7..bdc4090172 100644
--- a/backends/README.md
+++ b/backends/README.md
@@ -22,7 +22,7 @@ X seconds (though, it can send them per second if you need it to).
      metrics are sent to the backend server as `prefix.hostname.chart.dimension`. `prefix` is
      configured below, `hostname` is the hostname of the machine (can also be configured).
 
-   - **opentsdb** (`telnet interface`, used by **OpenTSDB**, **InfluxDB**, **KairosDB**, etc)
+   - **opentsdb** (`telnet or HTTP interfaces`, used by **OpenTSDB**, **InfluxDB**, **KairosDB**, etc)
 
      metrics are sent to opentsdb as `prefix.chart.dimension` with tag `host=hostname`.
 
@@ -76,7 +76,7 @@ of `netdata.conf` from your netdata):
 ```
 [backend]
     enabled = yes | no
-    type = graphite | opentsdb | json | prometheus_remote_write | kinesis
+    type = graphite | opentsdb:telnet | opentsdb:http | opentsdb:https | prometheus_remote_write | json | kinesis
     host tags = list of TAG=VALUE
     destination = space separated list of [PROTOCOL:]HOST[:PORT] - the first working will be used, or a region for kinesis
     data source = average | sum | as collected
@@ -92,7 +92,7 @@ of `netdata.conf` from your netdata):
 
 - `enabled = yes | no`, enables or disables sending data to a backend
 
-- `type = graphite | opentsdb | json | kinesis`, selects the backend type
+- `type = graphite | opentsdb:telnet | opentsdb:http | opentsdb:https | json | kinesis`, selects the backend type
 
 - `destination = host1 host2 host3 ...`, accepts **a space separated list** of hostnames,
    IPs (IPv4 and IPv6) and ports to connect to.
diff --git a/backends/backends.c b/backends/backends.c
index 7108a2a87d..15a0cb41b5 100644
--- a/backends/backends.c
+++ b/backends/backends.c
@@ -246,6 +246,194 @@ static void backends_main_cleanup(void *ptr) {
     static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
 }
 
+/**
+ * Set Kinesis variables
+ *
+ * Set the variables necessaries to work with this specific backend.
+ *
+ * @param default_port  the default port of the backend
+ * @param brc function called to check the result.
+ * @param brf function called to format the msessage to the backend
+ * @param type the backend string selector.
+ */
+void backend_set_kinesis_variables(int *default_port,
+                                   backend_response_checker_t brc,
+                                   backend_request_formatter_t brf)
+{
+    (void)default_port;
+#ifndef HAVE_KINESIS
+    (void)brc;
+    (void)brf;
+#endif
+
+#if HAVE_KINESIS
+    *brc = process_json_response;
+    if (BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED)
+        *brf = format_dimension_collected_json_plaintext;
+    else
+        *brf = format_dimension_stored_json_plaintext;
+#endif
+}
+
+/**
+ * Set Prometheus variables
+ *
+ * Set the variables necessaries to work with this specific backend.
+ *
+ * @param default_port  the default port of the backend
+ * @param brc function called to check the result.
+ * @param brf function called to format the msessage to the backend
+ * @param type the backend string selector.
+ */
+void backend_set_prometheus_variables(int *default_port,
+                                      backend_response_checker_t brc,
+                                      backend_request_formatter_t brf)
+{
+    (void)default_port;
+    (void)brf;
+#ifndef ENABLE_PROMETHEUS_REMOTE_WRITE
+    (void)brc;
+#endif
+
+#if ENABLE_PROMETHEUS_REMOTE_WRITE
+    *brc = process_prometheus_remote_write_response;
+#endif /* ENABLE_PROMETHEUS_REMOTE_WRITE */
+}
+
+/**
+ * Set JSON variables
+ *
+ * Set the variables necessaries to work with this specific backend.
+ *
+ * @param default_port  the default port of the backend
+ * @param brc function called to check the result.
+ * @param brf function called to format the msessage to the backend
+ * @param type the backend string selector.
+ */
+void backend_set_json_variables(int *default_port,
+                                backend_response_checker_t brc,
+                                backend_request_formatter_t brf)
+{
+    *default_port = 5448;
+    *brc = process_json_response;
+
+    if (BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED)
+        *brf = format_dimension_collected_json_plaintext;
+    else
+        *brf = format_dimension_stored_json_plaintext;
+}
+
+/**
+ * Set OpenTSDB HTTP variables
+ *
+ * Set the variables necessaries to work with this specific backend.
+ *
+ * @param default_port  the default port of the backend
+ * @param brc function called to check the result.
+ * @param brf function called to format the msessage to the backend
+ * @param type the backend string selector.
+ */
+void backend_set_opentsdb_http_variables(int *default_port,
+                                         backend_response_checker_t brc,
+                                         backend_request_formatter_t brf)
+{
+    *default_port = 4242;
+    *brc = process_opentsdb_response;
+
+    if(BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED)
+        *brf = format_dimension_collected_opentsdb_http;
+    else
+        *brf = format_dimension_stored_opentsdb_http;
+
+}
+
+/**
+ * Set OpenTSDB Telnet variables
+ *
+ * Set the variables necessaries to work with this specific backend.
+ *
+ * @param default_port  the default port of the backend
+ * @param brc function called to check the result.
+ * @param brf function called to format the msessage to the backend
+ * @param type the backend string selector.
+ */
+void backend_set_opentsdb_telnet_variables(int *default_port,
+                                           backend_response_checker_t brc,
+                                           backend_request_formatter_t brf)
+{
+    *default_port = 4242;
+    *brc = process_opentsdb_response;
+
+    if(BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED)
+        *brf = format_dimension_collected_opentsdb_telnet;
+    else
+        *brf = format_dimension_stored_opentsdb_telnet;
+}
+
+/**
+ * Set Graphite variables
+ *
+ * Set the variables necessaries to work with this specific backend.
+ *
+ * @param default_port  the default port of the backend
+ * @param brc function called to check the result.
+ * @param brf function called to format the msessage to the backend
+ * @param type the backend string selector.
+ */
+void backend_set_graphite_variables(int *default_port,
+                                    backend_response_checker_t brc,
+                                    backend_request_formatter_t brf)
+{
+    *default_port = 2003;
+    *brc = process_graphite_response;
+
+    if(BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED)
+        *brf = format_dimension_collected_graphite_plaintext;
+    else
+        *brf = format_dimension_stored_graphite_plaintext;
+}
+
+/**
+ * Select Type
+ *
+ * Select the backedn type based in the user input
+ *
+ * @param type is the string that defines the backend type
+ *
+ * @return It returns the backend id.
+ */
+BACKEND_TYPE backend_select_type(const char *type) {
+    if(!strcmp(type, "graphite") || !strcmp(type, "graphite:plaintext")) {
+        return BACKEND_TYPE_GRAPHITE;
+    }
+    else if(!strcmp(type, "opentsdb") || !strcmp(type, "opentsdb:telnet")) {
+        return BACKEND_TYPE_OPENTSDB_USING_TELNET;
+    }
+    else if(!strcmp(type, "opentsdb:http") || !strcmp(type, "opentsdb:https")) {
+        return BACKEND_TYPE_OPENTSDB_USING_HTTP;
+    }
+    else if (!strcmp(type, "json") || !strcmp(type, "json:plaintext")) {
+        return BACKEND_TYPE_JSON;
+    }
+    else if (!strcmp(type, "prometheus_remote_write")) {
+        return  BACKEND_TYPE_PROMETEUS;
+    }
+    else if (!strcmp(type, "kinesis") || !strcmp(type, "kinesis:plaintext")) {
+        return BACKEND_TYPE_KINESIS;
+    }
+
+    return BACKEND_TYPE_UNKNOWN;
+}
+
+/**
+ * Backend main
+ *
+ * The main thread used to control the backedns.
+ *
+ * @param ptr a pointer to netdata_static_structure.
+ *
+ * @return It always return NULL.
+ */
 void *backends_main(void *ptr) {
     netdata_thread_cleanup_push(backends_main_cleanup, ptr);
 
@@ -265,6 +453,9 @@ void *backends_main(void *ptr) {
     BUFFER *http_request_header = buffer_create(1);
 #endif
 
+#ifdef ENABLE_HTTPS
+            struct netdata_ssl opentsdb_ssl = {NULL , NETDATA_SSL_START};
+#endif
 
     // ------------------------------------------------------------------------
     // collect configuration options
@@ -313,76 +504,66 @@ void *backends_main(void *ptr) {
 
     // ------------------------------------------------------------------------
     // select the backend type
-
-    if(!strcmp(type, "graphite") || !strcmp(type, "graphite:plaintext")) {
-
-        default_port = 2003;
-        backend_response_checker = process_graphite_response;
-
-        if(BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED)
-            backend_request_formatter = format_dimension_collected_graphite_plaintext;
-        else
-            backend_request_formatter = format_dimension_stored_graphite_plaintext;
-
-    }
-    else if(!strcmp(type, "opentsdb") || !strcmp(type, "opentsdb:telnet")) {
-
-        default_port = 4242;
-        backend_response_checker = process_opentsdb_response;
-
-        if(BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED)
-            backend_request_formatter = format_dimension_collected_opentsdb_telnet;
-        else
-            backend_request_formatter = format_dimension_stored_opentsdb_telnet;
-
-    }
-    else if (!strcmp(type, "json") || !strcmp(type, "json:plaintext")) {
-
-        default_port = 5448;
-        backend_response_checker = process_json_response;
-
-        if (BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED)
-            backend_request_formatter = format_dimension_collected_json_plaintext;
-        else
-            backend_request_formatter = format_dimension_stored_json_plaintext;
-
-    }
-    else if (!strcmp(type, "kinesis") || !strcmp(type, "kinesis:plaintext")) {
-#if HAVE_KINESIS
-        do_kinesis = 1;
-
-        if(unlikely(read_kinesis_conf(netdata_configured_user_config_dir, &kinesis_auth_key_id, &kinesis_secure_key, &kinesis_stream_name))) {
-            error("BACKEND: kinesis backend type is set but cannot read its configuration from %s/aws_kinesis.conf", netdata_configured_user_config_dir);
-            goto cleanup;
-        }
-
-        kinesis_init(destination, kinesis_auth_key_id, kinesis_secure_key, timeout.tv_sec * 1000 + timeout.tv_usec / 1000);
-
-        backend_response_checker = process_json_response;
-        if (BACKEND_OPTIONS_DATA_SOURCE(global_backend_options) == BACKEND_SOURCE_DATA_AS_COLLECTED)
-            backend_request_formatter = format_dimension_collected_json_plaintext;
-        else
-            backend_request_formatter = format_dimension_stored_json_plaintext;
-#else
-        error("AWS Kinesis support isn't compiled");
-#endif /* HAVE_KINESIS */
-    }
-    else if (!strcmp(type, "prometheus_remote_write")) {
-#if ENABLE_PROMETHEUS_REMOTE_WRITE
-        do_prometheus_remote_write = 1;
-
-        backend_response_checker = process_prometheus_remote_write_response;
-
-        init_write_request();
-#else
-        error("Prometheus remote write support isn't compiled");
-#endif /* ENABLE_PROMETHEUS_REMOTE_WRITE */
-    }
-    else {
+    BACKEND_TYPE work_type = backend_select_type(type);
+    if (work_type == BACKEND_TYPE_UNKNOWN) {
         error("BACKEND: Unknown backend type '%s'", type);
         goto cleanup;
     }
 
+    switch (work_type) {
+        case BACKEND_TYPE_OPENTSDB_USING_HTTP: {
+#ifdef ENABLE_HTTPS
+            if (!strcmp(type, "opentsdb:https")) {
+                security_start_ssl(NETDATA_SSL_CONTEXT_OPENTSDB);
+            }
+#endif
+            backend_set_opentsdb_http_variables(&default_port,&backend_response_checker,&backend_request_formatter);
+            break;
+        }
+        case BACKEND_TYPE_PROMETEUS: {
+#if ENABLE_PROMETHEUS_REMOTE_WRITE
+            do_prometheus_remote_write = 1;
+
+            init_write_request();
+#else
+            error("BACKEND: Prometheus remote write support isn't compiled");
+#endif // ENABLE_PROMETHEUS_REMOTE_WRITE
+            backend_set_prometheus_variables(&default_port,&backend_response_checker,&backend_request_formatter);
+            break;
+        }
+        case BACKEND_TYPE_KINESIS: {
+#if HAVE_KINESIS
+            do_kinesis = 1;
+
+            if(unlikely(read_kinesis_conf(netdata_configured_user_config_dir, &kinesis_auth_key_id, &kinesis_secure_key, &kinesis_stream_name))) {
+                error("BACKEND: kinesis backend type is set but cannot read its configuration from %s/aws_kinesis.conf", netdata_configured_user_config_dir);
+                goto cleanup;
+            }
+
+            kinesis_init(destination, kinesis_auth_key_id, kinesis_secure_key, timeout.tv_sec * 1000 + timeout.tv_usec / 1000);
+#else
+            error("BACKEND: AWS Kinesis support isn't compiled");
+#endif // HAVE_KINESIS
+            backend_set_kinesis_variables(&default_port,&backend_response_checker,&backend_request_formatter);
+            break;
+        }
+        case BACKEND_TYPE_GRAPHITE: {
+            backend_set_graphite_variables(&default_port,&backend_response_checker,&backend_request_formatter);
+            break;
+        }
+        case BACKEND_TYPE_OPENTSDB_USING_TELNET: {
+            backend_set_opentsdb_telnet_variables(&default_port,&backend_response_checker,&backend_request_formatter);
+            break;
+        }
+        case BACKEND_TYPE_JSON: {
+            backend_set_json_variables(&default_port,&backend_response_checker,&backend_request_formatter);
+            break;
+        }
+        case BACKEND_TYPE_UNKNOWN: {
+            break;
+        }
+    }
+
 #if ENABLE_PROMETHEUS_REMOTE_WRITE
     if((backend_request_formatter == NULL && !do_prometheus_remote_write) || backend_response_checker == NULL) {
 #else
@@ -393,25 +574,25 @@ void *backends_main(void *ptr) {
     }
 
 
-    // ------------------------------------------------------------------------
-    // prepare the charts for monitoring the backend operation
+// ------------------------------------------------------------------------
+// prepare the charts for monitoring the backend operation
 
     struct rusage thread;
 
     collected_number
-            chart_buffered_metrics = 0,
-            chart_lost_metrics = 0,
-            chart_sent_metrics = 0,
-            chart_buffered_bytes = 0,
-            chart_received_bytes = 0,
-            chart_sent_bytes = 0,
-            chart_receptions = 0,
-            chart_transmission_successes = 0,
-            chart_transmission_failures = 0,
-            chart_data_lost_events = 0,
-            chart_lost_bytes = 0,
-            chart_backend_reconnects = 0;
-            // chart_backend_latency = 0;
+        chart_buffered_metrics = 0,
+        chart_lost_metrics = 0,
+        chart_sent_metrics = 0,
+        chart_buffered_bytes = 0,
+        chart_received_bytes = 0,
+        chart_sent_bytes = 0,
+        chart_receptions = 0,
+        chart_transmission_successes = 0,
+        chart_transmission_failures = 0,
+        chart_data_lost_events = 0,
+        chart_lost_bytes = 0,
+        chart_backend_reconnects = 0;
+        // chart_backend_latency = 0;
 
     RRDSET *chart_metrics = rrdset_create_localhost("netdata", "backend_metrics", NULL, "backend", NULL, "Netdata Buffered Metrics", "metrics", "backends", NULL, 130600, global_backend_update_every, RRDSET_TYPE_LINE);
     rrddim_add(chart_metrics, "buffered", NULL,  1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -432,12 +613,12 @@ void *backends_main(void *ptr) {
     rrddim_add(chart_ops, "read",      NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
 
     /*
-     * this is misleading - we can only measure the time we need to send data
-     * this time is not related to the time required for the data to travel to
-     * the backend database and the time that server needed to process them
-     *
-     * issue #1432 and https://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html
-     *
+    * this is misleading - we can only measure the time we need to send data
+    * this time is not related to the time required for the data to travel to
+    * the backend database and the time that server needed to process them
+    *
+    * issue #1432 and https://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html
+    *
     RRDSET *chart_latency = rrdset_create_localhost("netdata", "backend_latency", NULL, "backend", NULL, "Netdata Backend Latency", "ms", "backends", NULL, 130620, global_backend_update_every, RRDSET_TYPE_AREA);
     rrddim_add(chart_latency, "latency",   NULL,  1, 1000, RRD_ALGORITHM_ABSOLUTE);
     */
@@ -668,7 +849,16 @@ void *backends_main(void *ptr) {
                 while(sock != -1 && errno != EWOULDBLOCK) {
                     buffer_need_bytes(response, 4096);
 
-                    ssize_t r = recv(sock, &response->buffer[response->len], response->size - response->len, MSG_DONTWAIT);
+                    ssize_t r;
+#ifdef ENABLE_HTTPS
+                    if(opentsdb_ssl.conn && !opentsdb_ssl.flags) {
+                        r = SSL_read(opentsdb_ssl.conn, &response->buffer[response->len], response->size - response->len);
+                    } else {
+                        r = recv(sock, &response->buffer[response->len], response->size - response->len, MSG_DONTWAIT);
+                    }
+#else
+                    r = recv(sock, &response->buffer[response->len], response->size - response->len, MSG_DONTWAIT);
+#endif
                     if(likely(r > 0)) {
                         // we received some data
                         response->len += r;
@@ -701,7 +891,37 @@ void *backends_main(void *ptr) {
                 size_t reconnects = 0;
 
                 sock = connect_to_one_of(destination, default_port, &timeout, &reconnects, NULL, 0);
+#ifdef ENABLE_HTTPS
+                if(sock != -1) {
+                    if(netdata_opentsdb_ctx) {
+                        if(!opentsdb_ssl.conn) {
+                            opentsdb_ssl.conn = SSL_new(netdata_opentsdb_ctx);
+                            if(!opentsdb_ssl.conn) {
+                                error("Failed to allocate SSL structure %d.", sock);
+                                opentsdb_ssl.flags = NETDATA_SSL_NO_HANDSHAKE;
+                            }
+                        } else {
+                            SSL_clear(opentsdb_ssl.conn);
+                        }
+                    }
 
+                    if(opentsdb_ssl.conn) {
+                        if(SSL_set_fd(opentsdb_ssl.conn, sock) != 1) {
+                            error("Failed to set the socket to the SSL on socket fd %d.", host->rrdpush_sender_socket);
+                            opentsdb_ssl.flags = NETDATA_SSL_NO_HANDSHAKE;
+                        } else {
+                            opentsdb_ssl.flags = NETDATA_SSL_HANDSHAKE_COMPLETE;
+                            SSL_set_connect_state(opentsdb_ssl.conn);
+                            int err = SSL_connect(opentsdb_ssl.conn);
+                            if (err != 1) {
+                                err = SSL_get_error(opentsdb_ssl.conn, err);
+                                error("SSL cannot connect with the server:  %s ", ERR_error_string((long)SSL_get_error(opentsdb_ssl.conn, err), NULL));
+                                opentsdb_ssl.flags = NETDATA_SSL_NO_HANDSHAKE;
+                            } //TODO: check certificate here
+                        }
+                    }
+                }
+#endif
                 chart_backend_reconnects += reconnects;
                 // chart_backend_latency += now_monotonic_usec() - start_ut;
             }
@@ -756,7 +976,17 @@ void *backends_main(void *ptr) {
                 }
 #endif
 
-                ssize_t written = send(sock, buffer_tostring(b), len, flags);
+                ssize_t written;
+#ifdef ENABLE_HTTPS
+                if(opentsdb_ssl.conn && !opentsdb_ssl.flags) {
+                    written = SSL_write(opentsdb_ssl.conn, buffer_tostring(b), len);
+                } else {
+                    written = send(sock, buffer_tostring(b), len, flags);
+                }
+#else
+                written = send(sock, buffer_tostring(b), len, flags);
+#endif
+
                 // chart_backend_latency += now_monotonic_usec() - start_ut;
                 if(written != -1 && (size_t)written == len) {
                     // we sent the data successfully
@@ -883,6 +1113,14 @@ cleanup:
     buffer_free(b);
     buffer_free(response);
 
+#ifdef ENABLE_HTTPS
+    if(netdata_opentsdb_ctx) {
+        if(opentsdb_ssl.conn) {
+            SSL_free(opentsdb_ssl.conn);
+        }
+    }
+#endif
+
     netdata_thread_cleanup_pop(1);
     return NULL;
 }
diff --git a/backends/backends.h b/backends/backends.h
index 69a60e33de..8d0bda413a 100644
--- a/backends/backends.h
+++ b/backends/backends.h
@@ -15,6 +15,20 @@ typedef enum backend_options {
     BACKEND_OPTION_SEND_NAMES        = (1 << 16)
 } BACKEND_OPTIONS;
 
+typedef enum backend_types {
+    BACKEND_TYPE_UNKNOWN,                   //Invalid type
+    BACKEND_TYPE_GRAPHITE,                  //Send plain text to Graphite
+    BACKEND_TYPE_OPENTSDB_USING_TELNET,     //Send data to OpenTSDB using telnet API
+    BACKEND_TYPE_OPENTSDB_USING_HTTP,       //Send data to OpenTSDB using HTTP API
+    BACKEND_TYPE_JSON,                      //Stores the data using JSON.
+    BACKEND_TYPE_PROMETEUS,                 //The user selected to use Prometheus backend
+    BACKEND_TYPE_KINESIS                    //Send message to AWS Kinesis
+} BACKEND_TYPE;
+
+
+typedef int (**backend_response_checker_t)(BUFFER *);
+typedef int (**backend_request_formatter_t)(BUFFER *, const char *, RRDHOST *, const char *, RRDSET *, RRDDIM *, time_t, time_t, BACKEND_OPTIONS);
+
 #define BACKEND_OPTIONS_SOURCE_BITS (BACKEND_SOURCE_DATA_AS_COLLECTED|BACKEND_SOURCE_DATA_AVERAGE|BACKEND_SOURCE_DATA_SUM)
 #define BACKEND_OPTIONS_DATA_SOURCE(backend_options) (backend_options & BACKEND_OPTIONS_SOURCE_BITS)
 
diff --git a/backends/opentsdb/README.md b/backends/opentsdb/README.md
new file mode 100644
index 0000000000..3d57e2e1a6
--- /dev/null
+++ b/backends/opentsdb/README.md
@@ -0,0 +1,26 @@
+# OpenTSDB with HTTP
+
+Since version 1.16 the Netdata has the feature to communicate with OpenTSDB using HTTP API. To enable this channel
+it is necessary to set the following options in your netdata.conf
+
+```
+[backend]
+    type = opentsdb:http
+    destination = localhost:4242
+```
+
+, in this example we are considering that OpenTSDB is running with its default port (4242).
+
+## HTTPS
+
+Netdata also supports sending the metrics using SSL/TLS, but OpenTDSB does not have support to safety connections,
+so it will be necessary to configure a reverse-proxy to enable the HTTPS communication. After to configure your proxy the
+following changes must be done in the netdata.conf:
+
+```
+[backend]
+    type = opentsdb:https
+    destination = localhost:8082
+```
+
+In this example we used the port 8082 for our reverse proxy.
diff --git a/backends/opentsdb/opentsdb.c b/backends/opentsdb/opentsdb.c
index 6e3a31ab60..6ee559dbf3 100644
--- a/backends/opentsdb/opentsdb.c
+++ b/backends/opentsdb/opentsdb.c
@@ -80,6 +80,7 @@ int format_dimension_stored_opentsdb_telnet(
 
         return 1;
     }
+
     return 0;
 }
 
@@ -87,4 +88,118 @@ int process_opentsdb_response(BUFFER *b) {
     return discard_response(b, "opentsdb");
 }
 
+static inline void opentsdb_build_message(BUFFER *b, char *message, const char *hostname, int length) {
+    buffer_sprintf(
+            b
+            , "POST /api/put HTTP/1.1\r\n"
+              "Host: %s\r\n"
+              "Content-Type: application/json\r\n"
+              "Content-Length: %d\r\n"
+              "\r\n"
+              "%s"
+            , hostname
+            , length
+            , message
+    );
+}
 
+int format_dimension_collected_opentsdb_http(
+        BUFFER *b                 // the buffer to write data to
+        , const char *prefix        // the prefix to use
+        , RRDHOST *host             // the host this chart comes from
+        , const char *hostname      // the hostname (to override host->hostname)
+        , RRDSET *st                // the chart
+        , RRDDIM *rd                // the dimension
+        , time_t after              // the start timestamp
+        , time_t before             // the end timestamp
+        , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap
+) {
+    (void)host;
+    (void)after;
+    (void)before;
+
+    char message[1024];
+    char chart_name[RRD_ID_LENGTH_MAX + 1];
+    char dimension_name[RRD_ID_LENGTH_MAX + 1];
+    backend_name_copy(chart_name, (backend_options & BACKEND_OPTION_SEND_NAMES && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX);
+    backend_name_copy(dimension_name, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX);
+
+    int length =  snprintfz(message
+                           , sizeof(message)
+                           , "{"
+                             "  \"metric\": \"%s.%s.%s\","
+                             "  \"timestamp\": %llu,"
+                             "  \"value\": "COLLECTED_NUMBER_FORMAT ","
+                             "  \"tags\": {"
+                             "    \"host\": \"%s%s%s\""
+                             "  }"
+                             "}"
+                           , prefix
+                           , chart_name
+                           , dimension_name
+                           , (unsigned long long)rd->last_collected_time.tv_sec
+                           , rd->last_collected_value
+                           , hostname
+                           , (host->tags)?" ":""
+                           , (host->tags)?host->tags:""
+                    );
+
+    if(length > 0) {
+        opentsdb_build_message(b, message, hostname, length);
+    }
+
+    return 1;
+}
+
+int format_dimension_stored_opentsdb_http(
+        BUFFER *b                 // the buffer to write data to
+        , const char *prefix        // the prefix to use
+        , RRDHOST *host             // the host this chart comes from
+        , const char *hostname      // the hostname (to override host->hostname)
+        , RRDSET *st                // the chart
+        , RRDDIM *rd                // the dimension
+        , time_t after              // the start timestamp
+        , time_t before             // the end timestamp
+        , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap
+) {
+    (void)host;
+
+    time_t first_t = after, last_t = before;
+    calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, backend_options, &first_t, &last_t);
+
+    if(!isnan(value)) {
+        char chart_name[RRD_ID_LENGTH_MAX + 1];
+        char dimension_name[RRD_ID_LENGTH_MAX + 1];
+        backend_name_copy(chart_name, (backend_options & BACKEND_OPTION_SEND_NAMES && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX);
+        backend_name_copy(dimension_name, (backend_options & BACKEND_OPTION_SEND_NAMES && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX);
+
+        char message[1024];
+        int length =  snprintfz(message
+                , sizeof(message)
+                , "{"
+                  "  \"metric\": \"%s.%s.%s\","
+                  "  \"timestamp\": %llu,"
+                  "  \"value\": "CALCULATED_NUMBER_FORMAT ","
+                  "  \"tags\": {"
+                  "    \"host\": \"%s%s%s\""
+                  "  }"
+                  "}"
+                , prefix
+                , chart_name
+                , dimension_name
+                , (unsigned long long)last_t
+                , value
+                , hostname
+                , (host->tags)?" ":""
+                , (host->tags)?host->tags:""
+        );
+
+        if(length > 0) {
+            opentsdb_build_message(b, message, hostname, length);
+        }
+
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/backends/opentsdb/opentsdb.h b/backends/opentsdb/opentsdb.h
index fc83b39ca5..b9372d914b 100644
--- a/backends/opentsdb/opentsdb.h
+++ b/backends/opentsdb/opentsdb.h
@@ -31,5 +31,28 @@ extern int format_dimension_stored_opentsdb_telnet(
 
 extern int process_opentsdb_response(BUFFER *b);
 
+int format_dimension_collected_opentsdb_http(
+        BUFFER *b                 // the buffer to write data to
+        , const char *prefix        // the prefix to use
+        , RRDHOST *host             // the host this chart comes from
+        , const char *hostname      // the hostname (to override host->hostname)
+        , RRDSET *st                // the chart
+        , RRDDIM *rd                // the dimension
+        , time_t after              // the start timestamp
+        , time_t before             // the end timestamp
+        , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap
+);
+
+int format_dimension_stored_opentsdb_http(
+        BUFFER *b                 // the buffer to write data to
+        , const char *prefix        // the prefix to use
+        , RRDHOST *host             // the host this chart comes from
+        , const char *hostname      // the hostname (to override host->hostname)
+        , RRDSET *st                // the chart
+        , RRDDIM *rd                // the dimension
+        , time_t after              // the start timestamp
+        , time_t before             // the end timestamp
+        , BACKEND_OPTIONS backend_options // BACKEND_SOURCE_* bitmap
+);
 
 #endif //NETDATA_BACKEND_OPENTSDB_H
diff --git a/libnetdata/socket/security.c b/libnetdata/socket/security.c
index 6a02e4ef92..dcbd3f6508 100644
--- a/libnetdata/socket/security.c
+++ b/libnetdata/socket/security.c
@@ -2,6 +2,7 @@
 
 #ifdef ENABLE_HTTPS
 
+SSL_CTX *netdata_opentsdb_ctx=NULL;
 SSL_CTX *netdata_client_ctx=NULL;
 SSL_CTX *netdata_srv_ctx=NULL;
 const char *security_key=NULL;
@@ -10,6 +11,15 @@ int netdata_use_ssl_on_stream = NETDATA_SSL_OPTIONAL;
 int netdata_use_ssl_on_http = NETDATA_SSL_FORCE; //We force SSL due safety reasons
 int netdata_validate_server =  NETDATA_SSL_VALID_CERTIFICATE;
 
+/**
+ * Info Callback
+ *
+ * Function used as callback for the OpenSSL Library
+ *
+ * @param ssl a pointer to the SSL structure of the client
+ * @param where the variable with the flags set.
+ * @param ret the return of the caller
+ */
 static void security_info_callback(const SSL *ssl, int where, int ret) {
     (void)ssl;
     if (where & SSL_CB_ALERT) {
@@ -17,6 +27,11 @@ static void security_info_callback(const SSL *ssl, int where, int ret) {
     }
 }
 
+/**
+ * OpenSSL Library
+ *
+ * Starts the openssl library for the Netdata.
+ */
 void security_openssl_library()
 {
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
@@ -36,6 +51,13 @@ void security_openssl_library()
 #endif
 }
 
+/**
+ * OpenSSL common options
+ *
+ * Clients and SERVER have common options, this function is responsible to set them in the context.
+ *
+ * @param ctx
+ */
 void security_openssl_common_options(SSL_CTX *ctx) {
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
     static char *ciphers = {"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"};
@@ -55,10 +77,15 @@ void security_openssl_common_options(SSL_CTX *ctx) {
         error("SSL error. cannot set the cipher list");
     }
 #endif
-
-
 }
 
+/**
+ * Initialize Openssl Client
+ *
+ * Starts the client context with TLS 1.2.
+ *
+ * @return It returns the context on success or NULL otherwise
+ */
 static SSL_CTX * security_initialize_openssl_client() {
     SSL_CTX *ctx;
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
@@ -66,11 +93,20 @@ static SSL_CTX * security_initialize_openssl_client() {
 #else
     ctx = SSL_CTX_new(TLS_client_method());
 #endif
-    security_openssl_common_options(ctx);
+    if(ctx) {
+        security_openssl_common_options(ctx);
+    }
 
     return ctx;
 }
 
+/**
+ * Initialize OpenSSL server
+ *
+ * Starts the server context with TLS 1.2 and load the certificate.
+ *
+ * @return It returns the context on success or NULL otherwise
+ */
 static SSL_CTX * security_initialize_openssl_server() {
     SSL_CTX *ctx;
     char lerror[512];
@@ -116,18 +152,36 @@ static SSL_CTX * security_initialize_openssl_server() {
     return ctx;
 }
 
-void security_start_ssl(int type) {
-    if (!type) {
-        struct stat statbuf;
-        if (stat(security_key,&statbuf) || stat(security_cert,&statbuf)) {
-            info("To use encryption it is necessary to set \"ssl certificate\" and \"ssl key\" in [web] !\n");
-            return;
-        }
+/**
+ * Start SSL
+ *
+ * Call the correct function to start the SSL context.
+ *
+ * @param selector informs the context that must be initialized, the following list has the valid values:
+ *      NETDATA_SSL_CONTEXT_SERVER - the server context
+ *      NETDATA_SSL_CONTEXT_STREAMING - Starts the streaming context.
+ *      NETDATA_SSL_CONTEXT_OPENTSDB - Starts the OpenTSDB contextv
+ */
+void security_start_ssl(int selector) {
+    switch (selector) {
+        case NETDATA_SSL_CONTEXT_SERVER: {
+            struct stat statbuf;
+            if (stat(security_key,&statbuf) || stat(security_cert,&statbuf)) {
+                info("To use encryption it is necessary to set \"ssl certificate\" and \"ssl key\" in [web] !\n");
+                return;
+            }
 
-        netdata_srv_ctx =  security_initialize_openssl_server();
-    }
-    else {
-        netdata_client_ctx =  security_initialize_openssl_client();
+            netdata_srv_ctx =  security_initialize_openssl_server();
+            break;
+        }
+        case NETDATA_SSL_CONTEXT_STREAMING: {
+            netdata_client_ctx = security_initialize_openssl_client();
+            break;
+        }
+        case NETDATA_SSL_CONTEXT_OPENTSDB: {
+            netdata_opentsdb_ctx = security_initialize_openssl_client();
+            break;
+        }
     }
 }
 
@@ -142,6 +196,11 @@ void security_clean_openssl() {
         SSL_CTX_free(netdata_client_ctx);
     }
 
+    if ( netdata_opentsdb_ctx )
+    {
+        SSL_CTX_free(netdata_opentsdb_ctx);
+    }
+
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
     ERR_free_strings();
 #endif
diff --git a/libnetdata/socket/security.h b/libnetdata/socket/security.h
index dc0e910e70..8beb9672f2 100644
--- a/libnetdata/socket/security.h
+++ b/libnetdata/socket/security.h
@@ -11,6 +11,10 @@
 # define NETDATA_SSL_INVALID_CERTIFICATE 64  //Accepts invalid certificate
 # define NETDATA_SSL_VALID_CERTIFICATE 128  //Accepts invalid certificate
 
+#define NETDATA_SSL_CONTEXT_SERVER 0
+#define NETDATA_SSL_CONTEXT_STREAMING 1
+#define NETDATA_SSL_CONTEXT_OPENTSDB 2
+
 # ifdef ENABLE_HTTPS
 
 #  include <openssl/ssl.h>
@@ -24,6 +28,7 @@ struct netdata_ssl{
     int flags;
 };
 
+extern SSL_CTX *netdata_opentsdb_ctx;
 extern SSL_CTX *netdata_client_ctx;
 extern SSL_CTX *netdata_srv_ctx;
 extern const char *security_key;
@@ -34,7 +39,7 @@ extern int netdata_validate_server;
 
 void security_openssl_library();
 void security_clean_openssl();
-void security_start_ssl(int type);
+void security_start_ssl(int selector);
 int security_process_accept(SSL *ssl,int msg);
 int security_test_certificate(SSL *ssl);
 
diff --git a/streaming/rrdpush.c b/streaming/rrdpush.c
index f42056aa6e..954b1d7d19 100644
--- a/streaming/rrdpush.c
+++ b/streaming/rrdpush.c
@@ -651,7 +651,7 @@ void *rrdpush_sender_thread(void *ptr) {
 
 #ifdef ENABLE_HTTPS
     if (netdata_use_ssl_on_stream & NETDATA_SSL_FORCE ){
-        security_start_ssl(1);
+        security_start_ssl(NETDATA_SSL_CONTEXT_STREAMING);
     }
 #endif
 
diff --git a/web/server/static/static-threaded.c b/web/server/static/static-threaded.c
index 9f77c56a95..5dda27000b 100644
--- a/web/server/static/static-threaded.c
+++ b/web/server/static/static-threaded.c
@@ -458,7 +458,7 @@ void *socket_listen_main_static_threaded(void *ptr) {
                 fatal("LISTENER: no listen sockets available.");
 
 #ifdef ENABLE_HTTPS
-            security_start_ssl(0);
+            security_start_ssl(NETDATA_SSL_CONTEXT_SERVER);
 #endif
             // 6 threads is the optimal value
             // since 6 are the parallel connections browsers will do