diff --git a/README.md b/README.md
index 2761648..86257f9 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,19 @@ All modules define their logger via `logging.getLogger(__name__)`
 So in order to define specific logging format or level for this library use `getLogger('haystack')` or configure the
 root logger.
 
+### B3 propagation
+B3 propagation is supported by enabling the flag use_b3_propagation in HaystackTracer
+```python
+import opentracing
+from haystack import HaystackAgentRecorder
+from haystack import HaystackTracer
+use_b3_propagation = True
+tracer = HaystackTracer("a_service", HaystackAgentRecorder(), use_b3_propagation=use_b3_propagation)
+opentracing.set_global_tracer(tracer)
+```
+In order to set the appropriate headers with "X-B3-" format, please see above section "Custom propagation headers" for
+more information.
+
 ## How to configure build environment
 Create a python3 virtual environment, activate it and then `make bootstrap`
 
diff --git a/haystack/id_generator.py b/haystack/id_generator.py
new file mode 100644
index 0000000..bf0c6d2
--- /dev/null
+++ b/haystack/id_generator.py
@@ -0,0 +1,30 @@
+import uuid
+
+
+class IdGenerator:
+    def __init__(self):
+        pass
+
+    def generate(self):
+        """
+        Generates a UUID
+        """
+        return format(uuid.uuid4())
+
+    def generate_trace_id(self):
+        """"
+        Generates a b3 format compatible trace id
+        """
+        return self.__next_long()
+
+    def generate_span_id(self):
+        """"
+        Generates a b3 format compatible span id
+        """
+        return self.__next_long()
+
+    def __next_long(self):
+        random_number = uuid.uuid4()
+        while random_number.int == 0:
+            random_number = uuid.uuid4()
+        return random_number.hex
diff --git a/haystack/tracer.py b/haystack/tracer.py
index 56b1ab5..9224ea8 100644
--- a/haystack/tracer.py
+++ b/haystack/tracer.py
@@ -1,7 +1,8 @@
 import time
-import uuid
 from opentracing import Format, Tracer, UnsupportedFormatException
 from opentracing.scope_managers import ThreadLocalScopeManager
+
+from .id_generator import IdGenerator
 from .text_propagator import TextPropagator
 from .span import Span, SpanContext
 
@@ -13,7 +14,8 @@ def __init__(self,
                  recorder,
                  scope_manager=None,
                  common_tags=None,
-                 use_shared_spans=False):
+                 use_shared_spans=False,
+                 use_b3_propagation=False):
         """
         Initialize a Haystack Tracer instance.
         :param service_name: The service name to which all spans will belong.
@@ -26,6 +28,8 @@ def __init__(self,
         :param use_shared_spans: A boolean indicating whether or not to use
         shared spans. This is when client/server spans share the same span id.
         Default is to use unique span ids.
+        :param use_b3_propagation: A boolean indicating whether or not tu use
+        128 bit hex char ids instead of UUIDs.
         """
 
         scope_manager = ThreadLocalScopeManager() if scope_manager is None \
@@ -36,6 +40,7 @@ def __init__(self,
         self.service_name = service_name
         self.recorder = recorder
         self.use_shared_spans = use_shared_spans
+        self.use_b3_propagation = use_b3_propagation
         self.register_propagator(Format.TEXT_MAP, TextPropagator())
         self.register_propagator(Format.HTTP_HEADERS, TextPropagator())
 
@@ -90,7 +95,14 @@ def start_span(self,
             if scope is not None:
                 parent_ctx = scope.span.context
 
-        new_ctx = SpanContext(span_id=format(uuid.uuid4()))
+        id_generator = IdGenerator()
+        generated_span_id = id_generator.generate()
+        generated_trace_id = id_generator.generate()
+        if self.use_b3_propagation is not None and self.use_b3_propagation:
+            generated_span_id = id_generator.generate_span_id()
+            generated_trace_id = id_generator.generate_trace_id()
+
+        new_ctx = SpanContext(span_id=generated_span_id)
         if parent_ctx is not None:
             new_ctx.trace_id = parent_ctx.trace_id
             if parent_ctx.baggage is not None:
@@ -101,7 +113,7 @@ def start_span(self,
             else:
                 new_ctx.parent_id = parent_ctx.span_id
         else:
-            new_ctx.trace_id = format(uuid.uuid4())
+            new_ctx.trace_id = generated_trace_id
 
         # Set common tags
         if self._common_tags:
diff --git a/tests/unit/test_tracer.py b/tests/unit/test_tracer.py
index 96ef1d4..91afe22 100644
--- a/tests/unit/test_tracer.py
+++ b/tests/unit/test_tracer.py
@@ -59,6 +59,22 @@ def test_shared_spans_are_created_when_enabled(self):
         self.assertEqual(span.context.span_id, span_id)
         self.assertEqual(span.context.parent_id, parent_id)
 
+    def test_b3_format_ids_are_used_when_enabled(self):
+        tracer = HaystackTracer("any_service", NoopRecorder, use_b3_propagation=True)
+        span = tracer.start_span("any_operation")
+
+        self.assertTrue("-" not in span.context.trace_id)
+        self.assertTrue(len(span.context.trace_id) == 32)
+        self.assertTrue("-" not in span.context.span_id)
+        self.assertTrue(len(span.context.span_id) == 32)
+
+    def test_b3_format_ids_are_not_used_when_disabled(self):
+        tracer = HaystackTracer("any_service", NoopRecorder, use_b3_propagation=False)
+        span = tracer.start_span("any_operation")
+
+        self.assertTrue("-" in span.context.trace_id)
+        self.assertTrue("-" in span.context.span_id)
+
 
 if __name__ == "__main__":
     unittest.main()