diff --git a/docs/src/main/asciidoc/blaze-persistence.adoc b/docs/src/main/asciidoc/blaze-persistence.adoc
index 930c288aba8fc..b1dd6acda066e 100644
--- a/docs/src/main/asciidoc/blaze-persistence.adoc
+++ b/docs/src/main/asciidoc/blaze-persistence.adoc
@@ -16,6 +16,8 @@ queries which are then transformed to optimized queries that only fetch the data
The same DTO definitions can further be used for applying database updates, leading to a great reduction in boilerplate
code and removing the need for object mapping tools.
+include::./platform-include.adoc[]
+
== Setting up and configuring Blaze-Persistence
The extension comes with default producers for `CriteriaBuilderFactory` and `EntityViewManager` that work out of the
diff --git a/docs/src/main/asciidoc/cassandra.adoc b/docs/src/main/asciidoc/cassandra.adoc
new file mode 100644
index 0000000000000..89dc0314cae2a
--- /dev/null
+++ b/docs/src/main/asciidoc/cassandra.adoc
@@ -0,0 +1,597 @@
+////
+This guide is maintained in the main Quarkus repository
+and pull requests should be submitted there:
+https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
+////
+= Quarkus - Using the Cassandra Client
+
+include::./attributes.adoc[]
+
+Apache Cassandra® is a free and open-source, distributed, wide column store, NoSQL database
+management system designed to handle large amounts of data across many commodity servers, providing
+high availability with no single point of failure.
+
+In this guide, we will see how you can get your REST services to use a Cassandra database.
+
+include::./platform-include.adoc[]
+
+== Prerequisites
+
+To complete this guide, you need:
+
+* an IDE
+* JDK 1.8+ installed with `JAVA_HOME` configured appropriately
+* GraalVM installed with `GRAALVM_HOME` configured appropriately if you want to use the native mode.
+* Apache Maven {maven-version}
+* Cassandra or Docker installed
+
+== Architecture
+
+The application built in this guide is quite simple: the user can add elements in a list using a
+form, and the items list is updated.
+
+All the information between the browser and the server is formatted as JSON.
+
+The elements are stored in the Cassandra database.
+
+== Solution
+
+We recommend that you follow the instructions in the next sections and create the application step
+by step.
+However, you can go right to the completed example.
+
+The solution is located in the `quickstart`
+link:https://github.com/datastax/cassandra-quarkus/tree/master/quickstart[directory].
+
+== Creating the Maven project
+
+First, create a new Maven project and copy the `pom.xml` file that is present in the `quickstart`
+directory.
+
+The `pom.xml` is importing the RESTEasy/JAX-RS, JSON-B, Context Propagation and Cassandra Client
+extensions.
+
+We will be building a REST application using the
+link:https://docs.datastax.com/en/developer/java-driver/latest/manual/mapper[DataStax Object Mapper]
+to simplify the Data Access Layer code.
+
+The most important part of the `pom.xml` is adding the `cassandra-quarkus` extension:
+
+[source,xml]
+----
+
+ com.datastax.oss.quarkus
+ cassandra-quarkus-client
+ ${quarkus.version}
+
+----
+
+== Creating JSON REST service
+
+In this example, we will create an application to manage a list of fruits.
+
+First, let's create the `Fruit` bean as follows:
+
+[source,java]
+----
+@Entity
+public class Fruit {
+
+ @PartitionKey private String storeId;
+ @ClusteringColumn private String name;
+ private String description;
+
+ public Fruit() {}
+
+ public Fruit(String storeId, String name, String description) {
+ this.storeId = storeId;
+ this.name = name;
+ this.description = description;
+ }
+
+ // getters, setters, hashCode and equals omitted for brevity
+}
+----
+
+We are using DataStax Java driver Object Mapper, which is why this class is annotated with an
+`@Entity`. Also, the `storeId` field represents a Cassandra partition key and `name` represents a
+clustering column, and so we are using the corresponding annotations from the Object Mapper library.
+It will allow the Mapper to generate proper CQL queries underneath.
+
+IMPORTANT: Entity classes are required to have a default no-args constructor.
+
+To leverage the Mapper logic in this app we need to create a DAO:
+
+[source,java]
+----
+@Dao
+public interface FruitDao {
+ @Update
+ void update(Fruit fruit);
+
+ @Select
+ PagingIterable findById(String id);
+}
+----
+
+This class exposes operations that will be used in the REST service.
+
+Finally, the Mapper itself:
+
+[source,java]
+----
+@Mapper
+public interface FruitMapper {
+ @DaoFactory
+ FruitDao fruitDao();
+}
+----
+
+The mapper is responsible for constructing instances of `FruitDao`. In the example above, the
+`FruitDao` instance will be connected to the same keyspace as the underlying session. More on that
+below.
+
+TIP: It is also possible to create DAO instances for different keyspaces. To learn how, see
+link:https://docs.datastax.com/en/developer/java-driver/4.7/manual/mapper/mapper/#dao-parameterization[DAO parameterization]
+in the driver docs.
+
+Next, we need a component to create our DAO instances: `FruitDaoProducer`. Indeed, Mapper and Dao
+instances are stateful objects, and should be created only once, as application-scoped singletons.
+This component will do exactly that, leveraging Quarkus Dependency Injection container:
+
+[source, java]
+----
+import com.datastax.oss.driver.api.core.CqlIdentifier;
+import com.datastax.oss.quarkus.runtime.api.config.CassandraClientConfig;
+import com.datastax.oss.quarkus.runtime.api.session.QuarkusCqlSession;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+
+public class FruitDaoProducer {
+
+ private final FruitDao fruitDao;
+ private final FruitDaoReactive fruitDaoReactive;
+
+ @Inject
+ public FruitDaoProducer(QuarkusCqlSession session) {
+ // create a mapper
+ FruitMapper mapper = new FruitMapperBuilder(session).build();
+ // instantiate our Daos
+ fruitDao = mapper.fruitDao();
+ fruitDaoReactive = mapper.fruitDaoReactive();
+ }
+
+ @Produces
+ @ApplicationScoped
+ FruitDao produceFruitDao() {
+ return fruitDao;
+ }
+
+ @Produces
+ @ApplicationScoped
+ FruitDaoReactive produceFruitDaoReactive() {
+ return fruitDaoReactive;
+ }
+}
+----
+
+Note how the `QuarkusCqlSession` instance is injected automatically by the cassandra-quarkus
+extension in the `FruitDaoProducer` constructor.
+
+Now create a `FruitService` that will be the business layer of our application and store/load the
+fruits from the Cassandra database.
+
+[source,java]
+----
+@ApplicationScoped
+public class FruitService {
+
+ private final FruitDao dao;
+
+ @Inject
+ public FruitService(FruitDao dao) {
+ this.dao = dao;
+ }
+
+ public void save(Fruit fruit) {
+ dao.update(fruit);
+ }
+
+ public List get(String id) {
+ return dao.findById(id).all();
+ }
+}
+----
+
+Note how the service receives a `FruitDao` instance in the constructor. This DAO instance is
+provided by `FruitDaoProducer` and injected automatically.
+
+The last missing piece is the REST API that will expose GET and POST methods:
+
+[source,java]
+----
+@Path("/fruits")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class FruitResource {
+
+ private static final String STORE_NAME = "acme";
+
+ @Inject FruitService fruitService;
+
+ @GET
+ public List list() {
+ return fruitService.get(STORE_NAME).stream()
+ .map(fruit -> new FruitDto(fruit.getName(), fruit.getDescription()))
+ .collect(Collectors.toList());
+ }
+
+ @POST
+ public void add(FruitDto fruit) {
+ fruitService.save(covertFromDto(fruit));
+ }
+
+ private Fruit covertFromDto(FruitDto fruitDto) {
+ return new Fruit(fruitDto.getName(), fruitDto.getDescription(), STORE_NAME);
+ }
+}
+----
+
+The `list` and `add` operations are executed for the `storeId` "acme". This is the partition key of
+our data model. We can easily retrieve all rows from cassandra using that partition key.
+They will be sorted by the clustering column. `FruitResource` is using `FruitService` which
+encapsulates the data access logic.
+
+When creating the REST API we should not share the same entity object between REST API and data
+access layers. They should not be coupled to allow the API to evolve independently of the storage
+layer. This is the reason why the API is using a `FruitDto` class. This class will be used by
+Quarkus to convert JSON to java objects for client requests and java objects to JSON for the
+responses. The translation is done by quarkus-resteasy extension.
+
+[source,java]
+----
+public class FruitDto {
+
+ private String name;
+ private String description;
+
+ public FruitDto() {}
+
+ public FruitDto(String name, String description) {
+ this.name = name;
+ this.description = description;
+ }
+ // getters and setters omitted for brevity
+}
+----
+
+IMPORTANT: DTO classes used by the JSON serialization layer are required to have a default no-arg
+constructor.
+
+== Configuring the Cassandra database
+
+=== Connecting to Apache Cassandra or DataStax Enterprise (DSE)
+
+The main properties to configure are: `contact-points`, to access the Cassandra database,
+`local-datacenter`, which is required by the driver, and – optionally – the keyspace to bind to.
+
+A sample configuration should look like this:
+
+[source,properties]
+----
+quarkus.cassandra.contact-points={cassandra_ip}:9042
+quarkus.cassandra.local-datacenter={dc_name}
+quarkus.cassandra.keyspace={keyspace}
+----
+
+In this example, we are using a single instance running on localhost, and the keyspace containing
+our data is `k1`:
+
+[source,properties]
+----
+quarkus.cassandra.contact-points=127.0.0.1:9042
+quarkus.cassandra.local-datacenter=datacenter1
+quarkus.cassandra.keyspace=k1
+----
+
+If your cluster requires plain text authentication, you can also provide two more settings:
+`username` and `password`.
+
+[source,properties]
+----
+quarkus.cassandra.auth.username=john
+quarkus.cassandra.auth.password=s3cr3t
+----
+
+=== Connecting to a cloud DataStax Astra database
+
+When connecting to Astra, instead of providing a contact point and a datacenter, you should provide
+`secure-connect-bundle`, which should point to a valid path to an Astra secure connect bundle, as
+well as `username` and`password`, since authentication is always required on Astra clusters.
+
+A sample configuration for DataStax Astra should look like this:
+
+[source,properties]
+----
+quarkus.cassandra.cloud.secure-connect-bundle=/path/to/secure-connect-bundle.zip
+quarkus.cassandra.auth.username=john
+quarkus.cassandra.auth.password=s3cr3t
+quarkus.cassandra.keyspace=k1
+----
+
+=== Advanced driver configuration
+
+You can configure other Java driver settings using `application.conf` or `application.json` files.
+They need to be located in the classpath of your application.
+All settings will be passed automatically to the underlying driver configuration mechanism.
+Settings defined in `application.properties` with the `quarkus.cassandra` prefix will have priority
+over settings defined in `application.conf` or `application.json`.
+
+To see the full list of settings, please refer to the
+link:https://docs.datastax.com/en/developer/java-driver/latest/manual/core/configuration/reference/[driver settings reference].
+
+== Running a Cassandra Database
+
+By default, `CassandraClient` is configured to access a local Cassandra database on port 9042 (the
+default Cassandra port).
+
+IMPORTANT: Make sure that the setting `quarkus.cassandra.local-datacenter`
+matches the datacenter of your Cassandra cluster.
+
+TIP: If you don't know the name of your local datacenter, this value can be found by running the
+following CQL query: `SELECT data_center FROM system.local`.
+
+If you want to use Docker to run a Cassandra database, you can use the following command to launch
+one:
+
+[source,shell]
+----
+docker run \
+ --name local-cassandra-instance \
+ -p 7000:7000 \
+ -p 7001:7001 \
+ -p 7199:7199 \
+ -p 9042:9042 \
+ -p 9160:9160 \
+ -p 9404:9404 \
+ -d \
+ launcher.gcr.io/google/cassandra3
+----
+
+Note that only the 9042 port is required. All others all optional but provide enhanced features
+like JMX monitoring of the Cassandra instance.
+
+Next you need to create the keyspace and table that will be used by your application. If you are
+using Docker, run the following commands:
+
+[source,shell]
+----
+docker exec -it local-cassandra-instance cqlsh -e "CREATE KEYSPACE IF NOT EXISTS k1 WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}"
+docker exec -it local-cassandra-instance cqlsh -e "CREATE TABLE IF NOT EXISTS k1.fruit(id text, name text, description text, PRIMARY KEY((id), name))"
+----
+
+If you're running Cassandra locally you can execute the cqlsh commands directly:
+
+[source,shell]
+----
+cqlsh -e "CREATE KEYSPACE IF NOT EXISTS k1 WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}
+cqlsh -e "CREATE TABLE IF NOT EXISTS k1.fruit(id text, name text, description text, PRIMARY KEY((id), name))
+----
+
+== Creating a frontend
+
+Now let's add a simple web page to interact with our `FruitResource`.
+
+Quarkus automatically serves static resources located under the `META-INF/resources` directory.
+In the `src/main/resources/META-INF/resources` directory, add a `fruits.html` file with the content
+from this link:https://github.com/datastax/cassandra-quarkus/tree/master/quickstart/src/main/resources/META-INF/resources/fruits.html[fruits.html] file in it.
+
+You can now interact with your REST service:
+
+* start Quarkus with `mvn clean quarkus:dev`
+* open a browser to `http://localhost:8080/fruits.html`
+* add new fruits to the list via the form
+
+[[reactive]]
+== Reactive Cassandra Client
+
+When using `QuarkusCqlSession` you have access to reactive variant of methods that integrate with
+Quarkus and Mutiny.
+
+TIP: If you're not familiar with Mutiny, read the
+link:https://quarkus.io/guides/getting-started-reactive[Getting Started with Reactive guide] first.
+
+Let's rewrite the previous example using reactive programming with Mutiny.
+
+Firstly, we need to implement the `@Dao` that works in a reactive way:
+
+[source,java]
+----
+@Dao
+public interface FruitDaoReactive {
+
+ @Update
+ Uni updateAsync(Fruit fruitDao);
+
+ @Select
+ MutinyMappedReactiveResultSet findByIdAsync(String id);
+}
+
+----
+
+Please note the usage of `MutinyMappedReactiveResultSet` - it is a specialized `Mutiny` type
+converted from the original `Publisher` returned by the driver, which also exposes a few extra
+methods, e.g. to obtain the query execution info. If you don't need anything in that interface,
+you can also simply declare your method to return `Multi`: `Multi findByIdAsync(String id)`,
+
+Similarly, the method `updateAsync` returns a `Uni` - it is automatically converted from the
+original result set returned by the driver.
+
+NOTE: The Cassandra driver uses the Reactive Streams `Publisher` API for reactive calls. The Quarkus
+framework however uses Mutiny. Because of that, the `CqlQuarkusSession` interface transparently
+converts the `Publisher` instances returned by the driver into the reactive type `Multi`.
+`CqlQuarkusSession` is also capable of converting a `Publisher` into a `Uni` – in this case, the
+publisher is expected to emit at most one row, then complete. This is suitable for write queries
+(they return no rows), or for read queries guaranteed to return one row at most (count queries, for
+example).
+
+Next, we need to adapt the `FruitMapper` to construct a `FruitDaoReactive` instance:
+
+[source, java]
+----
+@Mapper
+public interface FruitMapper {
+ // the existing method omitted
+
+ @DaoFactory
+ FruitDaoReactive fruitDaoReactive();
+}
+
+----
+
+Now, we can create a `FruitReactiveService` that leverages the reactive `@Dao`:
+
+[source, java]
+----
+@ApplicationScoped
+public class FruitReactiveService {
+
+ private final FruitDaoReactive fruitDao;
+
+ @Inject
+ public FruitReactiveService(FruitDaoReactive fruitDao) {
+ this.fruitDao = fruitDao;
+ }
+
+ public Uni add(Fruit fruit) {
+ return fruitDao.update(fruit);
+ }
+
+ public Multi get(String id) {
+ return fruitDao.findById(id);
+ }
+}
+----
+
+NOTE: The `get()` method above returns `Multi`, and the `add()` method returns `Uni`; these types
+are compatible with the Quarkus reactive REST API.
+
+To integrate the reactive logic with REST API, you need to have a dependency to
+`quarkus-resteasy-mutiny`:
+
+[source, xml]
+----
+
+ io.quarkus
+ quarkus-resteasy-mutiny
+
+----
+
+It provides an integration layer between `Multi`, `Uni` and the REST API.
+
+Finally, we can create a `FruitReactiveResource`:
+
+[source, java]
+----
+@Path("/reactive-fruits")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class FruitReactiveResource {
+ private static final String STORE_NAME = "acme";
+ @Inject FruitReactiveService service;
+
+ @GET
+ public Multi getAll() {
+ return service
+ .get(STORE_NAME)
+ .map(fruit -> new FruitDto(fruit.getName(), fruit.getDescription()));
+ }
+
+ @POST
+ public Multi add(FruitDto fruitDto) {
+ Fruit fruit = covertFromDto(fruitDto);
+ return service.add(fruit).then(ignored -> getAll());
+ }
+
+ private Fruit covertFromDto(FruitDto fruitDto) {
+ return new Fruit(fruitDto.getName(), fruitDto.getDescription(), STORE_NAME);
+ }
+}
+----
+
+NOTE: All methods exposed via REST interface are returning reactive types from the Mutiny API.
+
+== Creating a reactive frontend
+
+Now let's add a simple web page to interact with our `FruitReactiveResource`.
+In the `src/main/resources/META-INF/resources` directory, add a `reactive-fruits.html` file with
+the content from this
+link:https://github.com/datastax/cassandra-quarkus/tree/master/quickstart/src/main/resources/META-INF/resources/reactive-fruits.html[reactive-fruits.html]
+file in it.
+
+You can now interact with your reactive REST service:
+
+* start Quarkus with `mvn clean quarkus:dev`
+* open a browser to `http://localhost:8080/reactive-fruits.html`
+* add new fruits to the list via the form
+
+
+== Connection Health Check
+
+If you are using the `quarkus-smallrye-health` extension, `cassandra-quarkus` will automatically
+add a readiness health check to validate the connection to the cluster.
+
+So when you access the `/health/ready` endpoint of your application you will have information about
+the connection validation status.
+
+TIP: This behavior can be disabled by setting the `quarkus.cassandra.health.enabled` property to
+`false` in your `application.properties`.
+
+== Metrics
+
+If you are using the `quarkus-smallrye-metrics` extension, `cassandra-quarkus` can provide metrics
+about QuarkusCqlSession and Cassandra nodes.
+
+TIP: This behavior must first be enabled by setting the `quarkus.cassandra.metrics.enabled`
+property to `true` in your `application.properties`.
+
+The next step that you need to do is set explicitly which metrics should be enabled.
+
+The `quarkus.cassandra.metrics.session-enabled` and `quarkus.cassandra.metrics.node-enabled`
+properties should be used for enabling metrics; the former should contain a list of session-level
+metrics to enable, while the latter should contain a list of node-level metrics to enable. Both
+properties accept a comma-separated list of valid metric names.
+
+For example, to enable `session.connected-nodes`, `session.bytes-sent`, and
+`node.pool.open-connections` you should add the following settings to your `application.properties`:
+
+[source, properties]
+----
+quarkus.cassandra.metrics.enabled=true
+quarkus.cassandra.metrics.session-enabled=connected-nodes,bytes-sent
+quarkus.cassandra.metrics.node-enabled=pool.open-connections
+----
+
+For the full list of available metrics, please refer to the
+link:https://docs.datastax.com/en/developer/java-driver/latest/manual/core/configuration/reference/[driver settings reference]
+and the `advanced.metrics` section.
+
+When metrics are properly enabled and when you access the `/metrics` endpoint of your application,
+you will see metric reports for all enabled metrics.
+
+== Building a native executable
+
+You can use the Cassandra client in a native executable.
+
+You can build a native executable with the `mvn clean package -Dnative` command.
+
+Running it is as simple as executing `./target/quickstart-1.0.0-SNAPSHOT-runner`.
+
+You can then point your browser to `http://localhost:8080/fruits.html` and use your application.
+
+== Conclusion
+
+Accessing a Cassandra database from a client application is easy with Quarkus and the Cassandra
+extension, which provides configuration and native support for the DataStax Java driver for
+Apache Cassandra.
\ No newline at end of file
diff --git a/docs/src/main/asciidoc/platform-include.adoc b/docs/src/main/asciidoc/platform-include.adoc
new file mode 100644
index 0000000000000..410c8451e3440
--- /dev/null
+++ b/docs/src/main/asciidoc/platform-include.adoc
@@ -0,0 +1,4 @@
+[NOTE]
+====
+This extension is developed by a third party and is part of the Quarkus Platform.
+====
\ No newline at end of file